--- old/src/share/classes/java/util/logging/LogManager.java Thu Jun 10 16:27:56 2010 +++ new/src/share/classes/java/util/logging/LogManager.java Thu Jun 10 16:27:52 2010 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -478,6 +478,12 @@ parent = nodeRef.get(); if (parent != null) { break; + } else { + // nodep holds a stale weak reference to a Logger + // which has been GC-ed. Note this will only cleanup + // stale weak refs that we encounter before we find + // our parent LogNode. + nodep.loggerRef = null; } } nodep = nodep.parent; @@ -489,6 +495,16 @@ // Walk over the children and tell them we are their new parent. node.walkAndSetParent(logger); + if (node.parent != null) { + // Look for possible weak reference cleanup from the new + // parent LogNode down. The walkAndSetParent() call above + // might have already done some or none of this work so + // this call is the only way to be absolutely sure we have + // checked for stale weak refs in every LogNode in the + // parent LogNode's hierarchy. + node.parent.deleteStaleWeakRefs(); + } + return true; } @@ -961,6 +977,11 @@ WeakReference ref = node.loggerRef; Logger logger = (ref == null) ? null : ref.get(); if (logger == null) { + // node holds a stale weak reference to a Logger + // which has been GC-ed. Note this will only cleanup + // stale weak refs that we encounter during our walk + // from the original node. + node.loggerRef = null; node.walkAndSetParent(parent); } else { doSetParent(logger, parent); @@ -967,6 +988,27 @@ } } } + + // Recursively delete stale WeakReferences on each of our children. + void deleteStaleWeakRefs() { + if (children == null) { + return; + } + Iterator values = children.values().iterator(); + while (values.hasNext()) { + LogNode node = values.next(); + WeakReference ref = node.loggerRef; + if (ref != null) { + Logger logger = ref.get(); + if (logger == null) { + // node holds a stale weak reference to a Logger + // which has been GC-ed. + node.loggerRef = null; + } + } + node.deleteStaleWeakRefs(); + } + } } // We use a subclass of Logger for the root logger, so