From: jra@gensym.com (Jim Allard)
Newsgroups: comp.lang.dylan
Subject: Re; GC Metering Module?
Date: 21 Jan 93 23:46:29 GMT

> Date: Tue, 19 Jan 93 17:49:13 EST
> From: harvard!cambridge.apple.com!moon (David A. Moon)
>
> If you feel like taking the trouble to write up some scenarios of how applications 
> would use a garbage collector interface, that would probably be helpful in 
> converging on an interface that we can standardize, although I'm still pessimistic 
> about that convergence happening soon.  The one part of your message that I 
> thought went in that direction was:
>
> > The explicit form to trigger garbage collects is for applications which know
> > the points at which most ephemeral objects have been released, for example
> > within the top level of the event loop.  This feature could also allow
> > applications to trigger garbage collection while the program is idle, rather
> > than when it is busy and needs to allocate more objects.
>
> Good idea, but I wonder if this needs some additional refinement since triggering 
> garbage collection every time a GC is a little more desirable than usual might 
> spend too much time collecting tiny amounts of garbage.  You want to GC only if 
> enough garbage has probably built up and enough idle time is available.  This is 
> all pretty implementation-dependent but perhaps there is a way to abstract away 
> the details?  There are papers on "opportunistic garbage collection" which are 
> relevant to this.

As you say, the form in the event loop would need some refining to avoid
calling the garbage collector needlessly, perhaps something like the following.
Please forgive the Common Lisp usage where I have no Dylan equivalent.  This
form also assumes there is a way to exit a get-event call at the appropriate
interval into an idle period.

  (bind ((ephemeral (first (allocation-areas)))
         (static (last (allocation-areas)))
         ((available-bytes integer) (area-available ephemeral)))
    (when (or (< available-bytes maximum-bytes-needed-per-event)
              (and (not (id? ephemeral static))
                   (> (- (get-universal-time) last-event-time)
                      idle-enough-to-gc-interval)
                   (< available-bytes (/ (area-size ephemeral) 2))))
      (garbage-collect ephemeral)))

If the maximum-bytes-needed-per-event value is determinable for an application
(and small enough to be realisticly used), then this form could guarantee two
things.  First, that GCs would occur when they are most likely to reclaim lots
of garbage.  Second, if there is any differentiation between areas in this
implementation, then a garbage collect will be triggered when half of available
memory in the shortest-lived area has been used up.

Another use that I would make of these tools would be to help manage objects
that I know will be long-lived.  The following could be an allocation function
that I would use for such an object.

  (bind ((original-area (selected-area)))
    (unwind-protect
      (begin
        (select-area (last (allocation-areas)))
        (make long-lived-jumbo))
      (select-area original-area)))

A third use I would make is for applications which show a lot of information to
users, in that I could sum up the area-size of each area in the the allocation
areas, and be able to report to my users a realistic total memory usage of my
application.

These examples are similar to things we have done in our products written in
Common Lisp, which had to be written as implementation-dependent code.  Though
needs will vary, our needs would pretty much be fulfilled by the forms I
suggested.

The problem issues I can think of for this approach would be where there are
different regions for different kinds of objects, instead of different
lifetimes.  This would shoot the ordering for allocation-areas in the foot, and
would make area selection be a little weird.  In this case, when an area is
selected, it could only be used for objects which could be allocated with in.

The attempt made in Common Lisp for this need was to provide a means of
emitting a textual report of memory statistics.  My attempt here was to provide
a programming interface to the kinds of operations I have seen and used in
Common Lisp implementations, biasing the interface towards supporting
generational collectors.

Jim
Newsgroups: comp.lang.dylan