如何通过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。
,那么整个画面就会改变
我想测试 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。