Hi Aaron
> It is useful also to initialise both popmemlim and popminmemlim to be
> as large as you can manage without causing paging. This requires some
> experimentation, and can depend on what else is using the computer.
(snip)
> Increasing popminmemlim forces the heap to expand before it has to, =
and
> can reduce the frequency of garbage collections, by having more space =
to
> 'turn over': the memory allocator runs out of free space less often.
The disadvantage of setting popminmemlim to a large size is that it =
causes
the application to have a large memory footprint. Customers would not be
happy with an application that on startup immediately consumed a =
significant proportion of their physical memory. Ideally an application =
should not even
draw attention to the fact that it requires tuning (e.g., long pauses)
and should exhibit sensible behaviour out of the box.
> As explained below, the cost of incremental GC would have been very
> high. The use of sys_lock_heap makes possible something a bit like
> generational GC, though it is not automated.
We did think about using sys_lock_heap at the time but decided against
it. Our application has several types of document-like objects that can
be opened and closed arbitrarily. We could open an object, GC, then lock
the heap without much problem (the GC should be short since it would
only include memory from the previous lock point). However, on closing
we would need to unlock the heap and GC in order to free whatever object
had been closed before locking the heap again. Since the GC would be
scanning the entire heap, it could be slow.
> John Gibson worked out a detailed scheme for incremental garbage
> collection at some time in the mid 1980s.
I think a generational GC (not necessarily an incremental GC) would be
a useful addition since it reflects the general behaviour that the =
longer
an object exists for, the less likely it is to become garbage.
The heap is split into segments, one of which is the "nursery" where
all new objects are allocated from. The nursery is GC'd when full -- any
surviving objects are moved to the next segment leaving the nursery
empty. When the next segment becomes full, that is GC'd and objects are
copied to a next (possibly final) segment. Eventually the final segment
would need to be GC'd just like the heap would be today. The benefit is
that scanning the relatively small nursery segment is likely to catch
most of the garbage, meaning that the ration of the number of objects
reclaimed per cpu cycle is higher than a complete scan of the heap
would be.
(Obviously there are some special cases e.g. if you're allocating a
structure that is too big for the nursery do you expand the nursery,
or break the generational approach by allocating it from the "youngest"
segment that can cope with it etc.)
> > 2. We also noticed we could improve overall performance if we =
increased
> > Java's "nursery" size (the area of memory where objects are first
> > created).
(snip)
> This appears to be analogous to increasing popminmemlim in pop11.
Not exactly (see the previous paragraph on generational GC) -- Sun's JVM
allows you to control both the nursery size and minimium heap size.
> One thing you did not mention was whether there was any difference in
> overall speed between the different versions of Clementine with =
similar
> functionality.
It's difficult to give any meaningful results since the two versions
never really had functional parity. The internal architectures were
very different and the first Java version was implemented with a large
number number of features that were not available in the final Pop-11
version.
Julian
|