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