src/share/classes/java/util/logging/Logger.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2000, 2006, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 182,191 ****
--- 182,194 ----
private static Object treeLock = new Object();
// We keep weak references from parents to children, but strong
// references from children to parents.
private volatile Logger parent; // our nearest parent.
private ArrayList<WeakReference<Logger>> kids; // WeakReferences to loggers that have us as parent
+ // marker to know if this Logger has already been visited during the
+ // current WeakReference cleanup pass
+ private int kidsCleanupMarker;
private volatile Level levelObject;
private volatile int levelValue; // current effective level value
/**
* GLOBAL_LOGGER_NAME is a name for the global logger.
*** 1386,1395 ****
--- 1389,1406 ----
WeakReference<Logger> ref = iter.next();
Logger kid = ref.get();
if (kid == this) {
iter.remove();
break;
+ } else if (kid == null) {
+ // Since we're already iterating the previous
+ // parent's kid list, remove any stale weak
+ // references to Logger objects that have been
+ // GC'ed. Note this will only cleanup stale weak
+ // refs that we encounter before we find ourself
+ // on the kids list.
+ iter.remove();
}
}
// We have now removed ourself from our parents' kids.
}
*** 1402,1411 ****
--- 1413,1431 ----
// As a result of the reparenting, the effective level
// may have changed for us and our children.
updateEffectiveLevel();
+ // Look for possible weak reference cleanup from the new
+ // parent Logger down. The updateEffectiveLevel() 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
+ // have checked for stale weak refs in every Logger in the
+ // parent Logger's hierarchy. See deleteStaleWeakRefs()
+ // below for why this marker is needed.
+ parent.kidsCleanupMarker = (int) System.currentTimeMillis();
+ parent.deleteStaleWeakRefs(parent.kidsCleanupMarker);
}
}
// Recalculate the effective level for this node and
// recursively for our children.
*** 1435,1451 ****
// System.err.println("effective level: \"" + getName() + "\" := " + level);
// Recursively update the level on each of our kids.
if (kids != null) {
! for (int i = 0; i < kids.size(); i++) {
! WeakReference<Logger> ref = kids.get(i);
Logger kid = ref.get();
if (kid != null) {
kid.updateEffectiveLevel();
}
}
}
}
// Private method to get the potentially inherited
--- 1455,1502 ----
// System.err.println("effective level: \"" + getName() + "\" := " + level);
// Recursively update the level on each of our kids.
if (kids != null) {
! for (Iterator<WeakReference<Logger>> iter = kids.iterator();
! iter.hasNext(); ) {
! WeakReference<Logger> ref = iter.next();
Logger kid = ref.get();
if (kid != null) {
kid.updateEffectiveLevel();
+ } else {
+ // Since we're already iterating this kid list,
+ // remove any stale weak references to Logger
+ // objects that have been GC'ed. Note this will
+ // only cleanup stale weak refs that we encounter
+ // when we have to update the effective Level value.
+ iter.remove();
}
}
+ }
+ }
+
+
+ // Recursively delete stale WeakReferences on each of our kids.
+ // The marker parameter is used to know if a kid has been visited
+ // before. This marker logic is needed because the Logging API
+ // currently permits loops to be created in the Logger hierarchy.
+ private void deleteStaleWeakRefs(int marker) {
+ if (kids != null) {
+ for (Iterator<WeakReference<Logger>> iter = kids.iterator();
+ iter.hasNext(); ) {
+ WeakReference<Logger> ref = iter.next();
+ Logger kid = ref.get();
+ if (kid == null) {
+ // Logger has been GC'ed so delete the stale weak ref
+ iter.remove();
+ } else if (kid.kidsCleanupMarker != marker) {
+ // visit the non-GC'ed Logger (and its kids, if any)
+ kid.kidsCleanupMarker = marker;
+ kid.deleteStaleWeakRefs(marker);
+ }
+ }
}
}
// Private method to get the potentially inherited