-
Bug
-
Resolution: Duplicate
-
P4
-
6u23
-
x86
-
linux
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.
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.
- duplicates
-
JDK-6942989 Memory leak of java.lang.ref.WeakReference objects
- Closed