Since the Inflater/Deflaters are not explicitly closed, their memory is only freed by the finalizer which cannot be relied upon to occur in a timely manner. So getting an OutOfMemoryError from this program is not a bug.
However, there may be a problem since the VM throws the error but does not crash in 1.4 and it throws then crashes in 1.4.1 and 1.4.2. Since the Inflater and Deflater java and native code has not changed in years, I don't think this is a libraries problem. I am moving the bug to runtime.
This is really two problems:
First, the libraries use a lot of non-Java (i.e., not garbage collectible) memory for these routines, which is preserved in the java memory and only deleted on finalize (from GC). The allocated space for the java memory item is itself very small. This has the effect of growing the total process space like crazy while the java allocated space remains quite small. This is demostrated by the use of GCALot, which forces GC. In that case, the process space remains small.
Second, the VM has places where it does not handle running out of memory. I suspect this will require significant effort to chase down.
The 1.5.0 vm correctly throws an OOM and exits w/o crashing, so I'm
closing this bug as 'not a bug'.
The JDC comment by rezaei says:
"How was this closed? The evaluation comment dated 2003-12-11
says "throws an OOM". That is NOT correct behavior for a
program that is not holding any references. The garbage
collector is badly broken if allocation of objects leads to
when no objects are reachable."
We're throwing an OOM not because the java heap is (anywhere close to) full,
but because the non-java (i.e., C/C++) heap is full: you can get an OOM
when either heap is full. The reason for the OOM is because unreachable, but
not yet finalized, java objects are holding pointers to C/C++ heap memory, and
that memory is deallocated pnly when the finalizers run. The JLS doesn't
specify when finalizers get run, so if the VM delays executing them long
enough, the C/C++ heap memory doesn't get freed soon enough to prevent an OOM.
I'm reopening the bug and transferring it to the gc group, because when to run
finalizers is a gc policy decision.
"I think we're seeing the usual problem with Java's inability to
collect non-heap-memory resources in a timely fashion.
The finalizable objects which can unmap the memory will be collected,
but the GC is not aware of the urgency, since they appear to be
simple small Java objects."
In the absence of a general solution to the non-heap resource
exhaustion problem, users of classes with close() methods should
make sure to call them as soon as possible.
The problem is more thoroughly explained in
5092131: using 1 MB pagesize throws "not enough space" error with 32bit JVM
###@###.### 10/15/04 20:51 GMT
Any attempt to fix this problem would require some surgery
of GC policy -- and to make the GC subsystem aware of
non-Java-heap resource exhaustion and to react to such
exhaustion with GC (presumably to get the finalizable
objects on to the reference handler queues) and tnen to
wait sufficiently long for the finalizers to run
before attempting to allocate said limited resource.
Such a policy architecture would take some effort to
implement properly, and will not be attempted for Mustang
because of, ahem, resource limitations. We are deferring
consideration of this bug to the Dolphin time-frame.
###@###.### 2005-04-22 02:31:53 GMT