This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
As Martin pointed out, adjusting GC_free_space_divisor should help.Hello Hans, and thanks for taking the time to think about this. We finally figured out - thanks to the Avtrex tool - what was going on. Once again, it turns out that the Boehm garbage collector was working perfectly all along, and that we had an "application problem".
That aside, I still don't understand this 100%. The large block allocator
does keep separate free lists for separate block sizes. (This changed a
while ago, but it has now done so for quite a long time.) Thus it should
not break up the 16K blocks used to hold 12932 byte objects until it has
used up the smaller ones. If this is not happening, there's a bug here.
(GC_dump() prints the large block free lists for each size, so this should
be fairly easy to check.)
If this is working correctly, garbage collections are simply being triggered too late. A GC_free_space_divisor increase should compensate. (I think that 7.0 will behave better in this respect, once it's integerated into gcj.)
Hans
On Tue, 21 Feb 2006, Craig A. Vanderborgh wrote:
class Parser {
static StringBuffer buffer = new StringBuffer;String method1 {
buffer.setLength(0);
<accumulate String in buffer>
return buffer.toString()
}
.
.
.
}private void ensureCapacity_unsynchronized (int minimumCapacity)
{
if (shared || minimumCapacity > value.length)
{
// We don't want to make a larger vector when `shared' is
// set. If we do, then setLength becomes very inefficient
// when repeatedly reusing a StringBuffer in a loop.
int max = (minimumCapacity > value.length
? value.length*2+2
: value.length);
minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
char[] nb = new char[minimumCapacity];
System.arraycopy(value, 0, nb, 0, count);
value = nb;
shared = false;
}
}public String toString ()
{
// Note: in libgcj this causes the StringBuffer to be shared. In
// Classpath it does not.
return new String (this);
}Regards, craig vanderborgh voxware incorporated
Hello Again!
First of all, thanks for the constructive replies to my previous "installment" from David and Rutger.
I have done a whole lot more testing and "dump diving" since then, and I have at least determined what is happening with our GCJ/Boehm "leaking". There is no leaking - or at least no leaking that I am concerned about in what I can see.
I believe the correct word for what is happening is "fragmentation". Hans also calls it "unexpectedly large heap growth". Maybe this latter term is the most appropriate. What is happening is pretty clear:
1. For processing a large-ish DOM element containing text, the application requests and receives a (say) 12932 block from GC. 2. This large-ish block is used to do the job, and then dereferenced. 3. Garbage collection happens, and the 12932-byte block is put back on the free list 4. The application requests a small block for a short string, and the collector decides to allocate the unused 12932 byte block, even though it's way too big. 5. Goto (1)
I have done enough logging and Daney-dumping to know that this how the heap becomes large. It does asymoptotically stabilize at a large value, but the value is too large for us to live with.
And so - what to do? Is it possible to instruct Boehm not to allocate block sizes above a certain threshold for short string char[]'s? Should the large-ish blocks be unmapped, so that this can't happen? Should I write some special-purpose classes that make use of CNI to use malloc() allocations so that these large-ish (12932) blocks are not requested from Boehm GC?
I also want to point out that I do have a "control" test now. On a test that does not have JS tags <script> with large texts in them, but is exactly the same otherwise, I get a steady-state heapsize of 1.5 MB instead of 13 MB, with all other things being equal. This shows that if my application does not ever request the 12932 blocks, things really work quite well with GCJ/Boehm allocation.
Please, if possible, help me reach a clue about how to proceed in the most constructive direction. This would be greatly appreciated.
Thanks in advance, craig vanderborgh voxware incorporated
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |