gcmanager.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 256 行

JAVA
256
字号
/*
 * $Id: GCManager.java,v 1.8 2004/02/24 09:03:29 epr Exp $
 */
package org.jnode.vm.memmgr.def;

import org.jnode.assembler.ObjectResolver;
import org.jnode.vm.Uninterruptible;
import org.jnode.vm.Unsafe;
import org.jnode.vm.Vm;
import org.jnode.vm.VmArchitecture;
import org.jnode.vm.VmSystem;
import org.jnode.vm.VmSystemObject;
import org.jnode.vm.classmgr.VmStatics;
import org.jnode.vm.memmgr.HeapHelper;

/**
 * @author epr
 */
final class GCManager extends VmSystemObject implements Uninterruptible {

    /** The heap manager */
    private final DefaultHeapManager heapManager;

    /** The mark stack */
    private final GCStack markStack;

    /** An object visitor used for marking */
    private final GCMarkVisitor markVisitor;

    /** An object visitor used for sweeping */
    private final GCSweepVisitor sweepVisitor;

    /** An object visitor used for setting objects to GC colour white */
    private final GCSetWhiteVisitor setWhiteVisitor;

    /** The object visitor that verifies the correctness of the object tree */
    private final GCVerifyVisitor verifyVisitor;

    /** My statistics */
    private final GCStatistics stats;

    /** The object resolver */
    private final ObjectResolver resolver;

    /** The statics table */
    private final VmStatics statics;

    /** The low level helper */
    private final HeapHelper helper;

    /** The write barrier */
    private final DefaultWriteBarrier writeBarrier;

    /** Debug mode? */
    private final boolean debug;

    /**
     * Create a new instance
     */
    public GCManager(DefaultHeapManager heapManager, VmArchitecture arch,
            VmStatics statics) {
        this.debug = Vm.getVm().isDebugMode();
        this.heapManager = heapManager;
        this.writeBarrier = (DefaultWriteBarrier) heapManager.getWriteBarrier();
        this.helper = heapManager.getHelper();
        this.markStack = new GCStack();
        this.markVisitor = new GCMarkVisitor(heapManager, arch, markStack);
        this.setWhiteVisitor = new GCSetWhiteVisitor(heapManager);
        this.verifyVisitor = new GCVerifyVisitor(heapManager, arch);
        this.sweepVisitor = new GCSweepVisitor(heapManager);
        this.stats = new GCStatistics();
        this.statics = statics;
        this.resolver = new Unsafe.UnsafeObjectResolver();
    }

    /**
     * Do a garbage collection cycle.
     */
    final void gc() {
        // Prepare
        final VmBootHeap bootHeap = heapManager.getBootHeap();
        final VmAbstractHeap firstHeap = heapManager.getFirstHeap();
        stats.lastGCTime = System.currentTimeMillis();

        final boolean locking = (writeBarrier != null);
        final boolean verbose = debug;
        helper.stopThreadsAtSafePoint();
        heapManager.setGcActive(true);
        try {
            // Mark
            //helper.stopThreadsAtSafePoint();
            //heapManager.setGcActive(true);
            try {
                if (verbose) {
                    Unsafe.debug("<mark/>");
                }
                markHeap(bootHeap, firstHeap, locking);
            } finally {
                //heapManager.setGcActive(false);
                //helper.restartThreads();
            }

            // Sweep
            if (verbose) {
                Unsafe.debug("<sweep/>");
            }
            sweep(firstHeap);

            // Cleanup
            if (verbose) {
                Unsafe.debug("<cleanup/>");
            }
            cleanup(bootHeap, firstHeap);

            // Verification
            if (debug) {
                if (verbose) {
                    Unsafe.debug("<verify/>");
                }
                verify(bootHeap, firstHeap);
            }
        } finally {
            heapManager.setGcActive(false);
            heapManager.resetCurrentHeap();
            helper.restartThreads();
        }

        // Start the finalization process
        heapManager.triggerFinalization();

        if (verbose) {
            Unsafe.debug("</gc free=");
            Unsafe.debug(heapManager.getFreeMemory());
            Unsafe.debug("/>");
            if (debug) {
                System.out.println(stats);
            }
        }
    }

    /**
     * Mark all live objects in the heap.
     * 
     * @param bootHeap
     * @param firstHeap
     */
    private final void markHeap(VmBootHeap bootHeap, VmAbstractHeap firstHeap,
            boolean locking) {

        if (writeBarrier != null) {
            writeBarrier.setActive(true);
        }

        final long startTime = VmSystem.currentKernelMillis();
        long markedObjects = 0;
        boolean firstIteration = true;
        boolean wbChanged = false;
        do {
            // Do an iteration reset
            markStack.reset();
            if (writeBarrier != null) {
                writeBarrier.resetChanged();
            }
            markVisitor.reset();
            markVisitor.setRootSet(true);
            statics.walk(markVisitor, resolver);
            // Mark every object in the rootset
            bootHeap.walk(markVisitor, locking, 0, 0);
            if (!firstIteration) {
                // If there was an overflow in the last iteration,
                // we must also walk through the other heap to visit
                // all grey objects, since we must still mark
                // their children.
                markVisitor.setRootSet(false);
                VmAbstractHeap heap = firstHeap;
                while ((heap != null) && (!markStack.isOverflow())) {
                    heap.walk(markVisitor, locking, 0, 0);
                    heap = heap.getNext();
                }
            }
            // Test for an endless loop
            if ((markVisitor.getMarkedObjects() == 0) && markStack.isOverflow()) {
                // Oops... an endless loop
                Unsafe.debug("Endless loop in markHeap.... going to die");
                helper.die("GCManager.markHeap");
            }
            // Do some cleanup
            markedObjects += markVisitor.getMarkedObjects();
            firstIteration = false;
            if (writeBarrier != null) {
                wbChanged = writeBarrier.isChanged();
            }
        } while (markStack.isOverflow() || wbChanged);
        final long endTime = VmSystem.currentKernelMillis();
        stats.lastMarkDuration = endTime - startTime;
        stats.lastMarkedObjects = markedObjects;

        if (writeBarrier != null) {
            writeBarrier.setActive(false);
        }
    }

    /**
     * Sweep all heaps for dead objects.
     * 
     * @param firstHeap
     */
    private void sweep(VmAbstractHeap firstHeap) {
        VmAbstractHeap heap = firstHeap;
        while (heap != null) {
            //freedBytes += heap.collect();
            sweepVisitor.setCurrentHeap(heap);
            heap.walk(sweepVisitor, true, 0, 0);
            heap = heap.getNext();
        }
    }

    /**
     * Mark all objects white, so a next GC action is valid
     * 
     * @param bootHeap
     * @param firstHeap
     */
    private void cleanup(VmBootHeap bootHeap, VmAbstractHeap firstHeap) {
        bootHeap.walk(setWhiteVisitor, true, 0, 0);
        VmAbstractHeap heap = firstHeap;
        while (heap != null) {
            heap.defragment();
            //heap.walk(setWhiteVisitor, locking);
            heap = heap.getNext();
        }
    }

    /**
     * Verify all heaps.
     * 
     * @param bootHeap
     * @param firstHeap
     */
    private void verify(VmBootHeap bootHeap, VmAbstractHeap firstHeap) {
        verifyVisitor.reset();
        bootHeap.walk(verifyVisitor, true, 0, 0);
        VmAbstractHeap heap = firstHeap;
        while (heap != null) {
            heap.walk(verifyVisitor, true, 0, 0);
            heap = heap.getNext();
        }
        final int errorCount = verifyVisitor.getErrorCount();
        if (errorCount > 0) {
            Unsafe.debug(errorCount);
            Unsafe.debug(" verify errors. ");
            helper.die("Corrupted heap");
        }
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?