如何通过Monitor Used Object理解GC Root?

how to understand GC Root by Monitor Used Object?

我想测试 Monitor Used 对象作为 GC 根,代码如下

package cn.jast.jvm.gcroot;

/**
 * Monitor Used - objects used as a monitor for synchronization
 *
 * Created by jast90 on 2021/1/9
 */
public class GCRootMonitorUsed {
    BigClass bigClass = new BigClass();
    BigClass lock = new BigClass();

    public static void main(String[] args) {
        PrintMemoryUtil.printMemory();
        GCRootMonitorUsed gcRootMonitorUsed = new GCRootMonitorUsed();
        System.out.println("after create big class");
        PrintMemoryUtil.printMemory();
        System.gc();
        System.out.println("first gc");
        PrintMemoryUtil.printMemory();
        synchronized (gcRootMonitorUsed.lock){
            gcRootMonitorUsed = null;
            System.gc();
            System.out.println("second gc");
            PrintMemoryUtil.printMemory();
            System.gc();
            System.out.println("third gc");
            PrintMemoryUtil.printMemory();
        }
    }

    /*
    // move to a java file as not inner class
    class BigClass{
        private int _10MB = 10 * 1024 * 1024;
        private byte[] memory = new byte[8 * _10MB];
    }*/
}
package cn.jast.jvm.gcroot;

/**
 * Created by jast90 on 2021/1/9
 */
public class PrintMemoryUtil {

    public static void printMemory(){
        System.out.println("free is :"+Runtime.getRuntime().freeMemory()/1024/1024 + "M");
        System.out.println("total is :"+Runtime.getRuntime().totalMemory()/1024/1024 + "M");
    }
}

结果是:

free is :120M
total is :123M
after create big class
free is :40M
total is :203M
first gc
free is :42M
total is :203M
second gc
free is :42M
total is :203M
third gc
free is :42M
total is :203M

参考

来自您自己的参考:

假设参考是正确的,我会将其解释为:

synchronized(obj) {
  // obj used as monitor
}
// obj free to collect

内部 class BigClass 的实例隐式引用了外部 class GCRootMonitorUsed。只要您保持对 BigClass 实例的引用,您还持有对封闭 GCRootMonitorUsed 实例的隐式引用。

gcRootMonitorUsed.lock 上同步会为同步块的整个运行时创建对 gcRootMonitorUsed.lock 的强引用,因此会创建对 GCRootMonitorUsed 实例的强引用。

如果 BigClass 是一个静态嵌套 class,它不会引用外部 class。

,那么整个画面就会改变