JDK-4797189 : Finalizers not called promptly enough
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version:
    1.1.6,1.3.1_12,1.4.1,1.4.2,6u7-rev,6u10,6u23 1.1.6,1.3.1_12,1.4.1,1.4.2,6u7-rev,6u10,6u23
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • OS:
    generic,solaris_7,solaris_9,solaris_10,windows_2000 generic,solaris_7,solaris_9,solaris_10,windows_2000
  • CPU: generic,x86,sparc
  • Submitted: 2002-12-21
  • Updated: 2014-04-08
  • Resolved: 2012-04-10
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Name: nt126004			Date: 12/20/2002

java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)

SunOS 5.9 Generic_112233-02 sun4u sparc SUNW,Sun-Fire-880

Linux 2.4.18-17.8.0 #1 Tue Oct 8 13:51:08 EDT 2002 i686 i686
i386 GNU/Linux

The JVM seems to have a memory leak: when run with the -Xmx
and -Xms options, then the JVM seems to start filling up all
the available memory of the system, and then throws an out
of memory exception.

Even without using the -Xm* options the program grows uncontrolably on Solaris.

The problem presents both on a Red-hat Linux system and on a
Solaris system, even using -Xint or -Xfuture options.
Maybe also other systems are affected by this bug, though I
cannot confirm.

1. Run the included program
2. the system will swap and eventually you'll have an OutOfMemoryError and 
a core dump.

Obviously, I didn't expect it to fill up all my memory :-)

This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.zip.*;

public class Bug {
        public static void main( String args[] ) {
                while ( true ) {
                        /* If ANY of these two lines is not commented, the JVM
                         runs out of memory */
                        final Deflater deflater = new Deflater( 9, true );
                        final Inflater inflater = new Inflater( true );
---------- END SOURCE ----------

One way to avoid the problem is by passing the -Xincgc
option to the JVM
(Review ID: 173339) 
###@###.### 10/15/04 20:43 GMT

EVALUATION This particular problem with Infator can likely be resolved by using java2d disposer or similar approach.

EVALUATION 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. ###@###.### 2003-01-06 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. ###@###.### 2003-01-07 The 1.5.0 vm correctly throws an OOM and exits w/o crashing, so I'm closing this bug as 'not a bug'. ###@###.### 2003-12-11 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. ###@###.### 2004-01-05 "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

WORK AROUND Invoke "end()" on any Inflator or Deflator once it is no longer in use. This will clean up the process space (non Java/GC) memory. ###@###.### 2003-01-07 Read 5092131 for more work around ideas. ###@###.### 10/15/04 20:51 GMT