JDK-7020446 : Logger Memory Leak
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.logging
  • Affected Version: 6u23
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2011-02-17
  • Updated: 2012-03-20
  • Resolved: 2011-07-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbd_majorResolved
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
Java(TM) SE Runtime Environment (build 1.6.0_22-b04-307-10M3261)

A DESCRIPTION OF THE PROBLEM :
Calls to private java.util.logging.Logger.doSetParent(Logger newParent) will result in a memory leak when the referent value in the WeakReference in the parent.kids array list has been garbage collected.

This code in Logger.doSetParent() - the private method -  is not correct and could result in the ArrayList not ever removing the WeakReference in the ArrayList and adding a new one every time there was a GC and then calling doSetParent() for the same logger.

if (parent != null) {
    for (Iterator iter = parent.kids.iterator(); iterator.hasNext();) {
        WeakReference ref = (WeakReference)iter.next();
        Logger kid = (Logger)ref.get();
        if (kid == this) {
             iter.remove();
        }
        break;
}

In the above code, the "ref" variable will be null after a GC occurs for the logger being held onto by the WeakReference so the array list entry will never be removed. Then later in the code in the same method, you'll add another entry for the logger "parent.kids.add(new WeakReference(this));

The end result is that you'll end up with an never ending growing kids collection and a memory leak.

The above code needs to work like the remove in the LogManager.addLogger() method where they use a hashtable for the loggers variablle instead of an arraylist and they look up the logger by name key (which they will find) and remove the hashtable entry if the WeakReference's referent value is null.

So, the above code needs to change to this:

WeakReference <Logger> ref = kids.get(this.getName());
if (ref != null) {
    if (ref.get() == null) {
       kids.remove(this);
    }
}



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
- Make a call to Logger.getLogger("foo") where foo has a logger parent.
- do a GC.
- Make another call to Logger.getLogger("foo") where foo has the same parent as before.
- Notice that in Logger.doSetParent() , the private method, will not remove the old array list entry for the foo logger and add a new one.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The Logger.parent.kids collection doesn't have a memory leak.
ACTUAL -
The Logger.parent.kids collection has a memory leak.

REPRODUCIBILITY :
This bug can be reproduced always.

Comments
EVALUATION Closing as a duplicate of 6942989.
11-07-2011

EVALUATION I believe this is a duplicate of the following bug: 6942989 2/2 Memory leak of java.lang.ref.WeakReference objects Alan, thanks for pointing that out. The fix for 6942989 has been backported to the JDK6-Update train and is making it's way through the integration and release process. This bug does not have a test case so I can't verify that the fix for 6942989 solves that specific test case failure.
18-02-2011