Heap fragmentation (Was: Debugging "Leaks" With Boehm-GC)
David Daney
ddaney@avtrex.com
Sun Jan 15 00:41:00 GMT 2006
Martin Egholm Nielsen wrote:
> Hi,
>>>> We are currently experiencing some dire difficulties with one of
>>> GCJ's most opaque aspects - garbage collection.
>>>>>> The application exhibiting "leaks" is an XML browser of our own
>>> creation. The use case that "leaks" is one where our browser
>>> software works its way through interpreting some page elements, and
>>> then throws an "event", which is implemented by throwing a Java
>>> exception, which something up the stack elements then catches. The
>>> software works beautifully, except it "leaks".
>>>> The boehm GC in certain circumstances suffers from memory
>> fragmentation. When this happens, even though there may be 'free'
>> memory, it cannot be used so the GC must try to obtain more memory
>> from the OS.
>>>> The solution we found was to increase the GC_free_space_divisor (to a
>> value of 20). Using this in conjunction with calling
>> _Jv_SetMaximumHeapSize() to set the maximum heap size gives us very
>> good results (A fixed heap size that never fills up). There is a
>> trade off in increasing the GC_free_space_divisor, in that it
>> increases the frequency of GC events with results in reduced performance.
>>> Just stumpled across this old thread - seems that I'm beginning to run
> into fragmentation problems - bot being able to allocate memory for some
> things.
> I have set GC_MAXIMUM_HEAP_SIZE to 14000000 (14mb), but I wonder where I
> can configure GC_free_space_divisor? In "alloc.c" it seems - but there
> it's set to 3, whereas "gc.h" says it's initially 4?!
>We set GC_free_space_divisor before calling JvRunMain. I don't know
what happens if you call it after the runtime is already started.
> Moreover, is 20 a super value? Or is this trial-and-error?
>
Trial and error.
The larger the divisor, the more time spent in GC, but the less likely
you are to end up in the pathological situation where there is plenty of
free memory, but it is all in pools for objects of a size other than you
are trying to allocate.
I think the default value is probably appropiate for cases where there
is no upper bound on memory size. For bounded memory size, we have
found that a larger divisor is needed.
David Daney
More information about the Java
mailing list