/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.vm.memmgr.def; import org.jnode.annotation.MagicPermission; import org.jnode.bootlog.BootLogInstance; import org.jnode.vm.classmgr.ObjectFlags; import org.jnode.vm.scheduler.Monitor; import org.vmmagic.unboxed.Word; /** * Thread used to invoke the {@link java.lang.Object#finalize()}method of all * objects that are about to be reclamed. * * @author Ewout Prangsma (epr@users.sourceforge.net) */ @MagicPermission final class FinalizerThread extends Thread { /** * The heap manager */ private final DefaultHeapManager heapManager; /** * Monitor for synchronizing access to my fields */ private final Monitor monitor; /** * The number of triggers received */ private int triggerCount; /** * The number of finalization runs performed */ private int runCount; /** * My visitor */ private final FinalizerVisitor visitor; /** * Initialize this instance. * * @param heapManager */ public FinalizerThread(DefaultHeapManager heapManager) { super("finalizer-thread"); this.heapManager = heapManager; this.monitor = new Monitor(); this.visitor = new FinalizerVisitor(heapManager.getHelper()); } /** * Trigger a GC run. * * @param waitToFinish If true, block until the run is ready, if false, return * immediately. */ public final void trigger(boolean waitToFinish) { triggerCount++; monitor.enter(); try { monitor.NotifyAll(); if (waitToFinish) { while (triggerCount != runCount) { try { monitor.Wait(0L); } catch (InterruptedException ex) { // Ignore } } } } finally { monitor.exit(); } } /** * Continue to call runFinalization. * * @see java.lang.Runnable#run() */ public final void run() { while (true) { try { monitor.enter(); try { while (triggerCount == runCount) { monitor.Wait(0L); } runFinalization(); runCount++; monitor.NotifyAll(); } finally { monitor.exit(); } } catch (Throwable ex) { try { BootLogInstance.get().error("Error in FinalizerThread", ex); } catch (Throwable ex2) { // Ignore } } } } /** * Go through all heaps and run the finalize method of all objects that * are unreachable and still need finalization. */ private final void runFinalization() { VmDefaultHeap heap = heapManager.getHeapList(); final Word colorMask = Word.fromIntZeroExtend(ObjectFlags.GC_COLOUR_MASK); final Word yellow = Word.fromIntZeroExtend(ObjectFlags.GC_YELLOW); while (heap != null) { visitor.setCurrentHeap(heap); heap.walk(visitor, true, colorMask, yellow); heap = heap.getNext(); } } }