精华内容
下载资源
问答
  • 2021-06-20 19:11:28

    在Java语言中,GC Roots包括以几类元素:

    1、虚拟机栈中引用的对象

         ➢比如:各个线程被调用的方法中使用到的参数、局部变量等(局部变量表)。

    2、本地方法栈内JNI (通常说的本地native方法)引用的对象

    3、方法区中类静态属性引用的对象

          ➢比如: Java类的引用类型静态变量

    4、方法区中常量引用的对象

         ➢比如:字符串常量池(String Table)里的引用

    5、所有被同步锁synchroni zed持有的对象

    6、Java虚拟机内部的引用。

          ➢基本数据类型对应的Class对象,一些常驻的异常对象(如:Nul1PointerException、outofMemoryError) ,系统类加载器。

    7、反映j ava虛拟机内部情况的JMXBean、 JVMTI中注册的回调、本地代码缓存等。

    除了这些固定的GC Roots集合以外,根据用户所选用的垃圾收集器以及当前回收的内存区域不同,还可以有其他对象“临时性”地加入,共同构成完整GC Roots集合。比如:分代收集和局部回收(Partial GC)。

    ➢如果只针对Java堆中的某一块区域进行垃圾回收(比如:典型的只针对新生代),必须考虑到内存区域是虚拟机自己的实现细节,更不是孤立封闭的,这个区域的对象完全有可能被其他区域的对象所引用,这时候就需要一并将关联的区域对象也加入GC Roots集合中去考虑,才能保证可达性分析的准确性。

    小技巧:

    由于Root采用栈方式存放变量和指针,所以如果一个指针,它保存了堆内存里面的对象,但是自己又不存放在堆内存里面,那它就是一个Root。

    注意:
    如果要使用可达性分析算法来判断内存是否可回收,那么分析工作必须在一个能保障一致性的快照中进行这点不满足的话分析结果的准确性就无法保证。

    这点也是导致GC进行时必须"Stop The World"的一个重要原因。

    ➢即使是号称(几乎)不会发生停顿的CMS收集器中,枚举根节点时也是必须要停顿的。
     

    更多相关内容
  • 一、名词解释根搜索算法是JVM用来的判断对象是否存活的算法,此算法基本思路为通过一系列的“GC Roots”对象作为起始点,从这些节点往下搜索,当一个对象和GC Roots不可达时,则该对象是无用的,可被回收的。...

    一、名词解释

    根搜索算法是JVM用来的判断对象是否存活的算法,此算法基本思路为通过一系列的“GC Roots”对象作为起始点,从这些节点往下搜索,当一个对象和GC Roots不可达时,则该对象是无用的,可被回收的。如下图所示:object5、object6、object7虽然互相有关联,但是他们到GC Roots是不可达的,因此他们都可以被回收。

    在java中,可作为GC Roots的对象有:

    1.虚拟机栈(栈帧中的本地变量表)中引用的对象;

    2.方法区中的类静态属性引用的对象;

    3.方法区中常量引用的对象;

    4.本地方法栈中JNI(即一般说的Native方法)中引用的对象

    二、验证以上可作为GC Roots的对象(此处只做最简单的验证,不涉及很复杂的GCRoots引用链)。

    1.验证虚拟机栈(栈帧中的局部变量)中引用的对象 作为GC Roots

    /**

    * GCRoots 测试:虚拟机栈(栈帧中的局部变量)中引用的对象作为GCRoots

    * -Xms1024m -Xmx1024m -Xmn512m -XX:+PrintGCDetails

    *

    * 扩展:虚拟机栈中存放了编译器可知的八种基本数据类型,对象引用,returnAddress类型(指向了一条字节码指令的地址)

    * @author ljl

    */

    public class TestGCRoots01 {

    private int _10MB = 10 * 1024 * 1024;

    private byte[] memory = new byte[8 * _10MB];

    public static void main(String[] args) {

    method01();

    System.out.println("返回main方法");

    System.gc();

    System.out.println("第二次GC完成");

    }

    public static void method01() {

    TestGCRoots01 t = new TestGCRoots01();

    System.gc();

    System.out.println("第一次GC完成");

    }

    }

    控制台打印日志:

    [GC [PSYoungGen: 105513K->616K(458752K)] 105513K->82536K(983040K), 0.0945986 secs] [Times: user=0.17 sys=0.06, real=0.09 secs]

    [Full GC [PSYoungGen: 616K->0K(458752K)] [ParOldGen: 81920K->82430K(524288K)] 82536K->82430K(983040K) [PSPermGen: 2547K->2546K(21504K)], 0.0273364 secs] [Times: user=0.06 sys=0.01, real=0.03 secs]

    第一次GC完成

    返回main方法

    [GC [PSYoungGen: 15728K->64K(458752K)] 98159K->82494K(983040K), 0.0014739 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

    [Full GC [PSYoungGen: 64K->0K(458752K)] [ParOldGen: 82430K->510K(524288K)] 82494K->510K(983040K) [PSPermGen: 2546K->2546K(21504K)], 0.0118484 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]

    第二次GC完成

    第一次GC:

    t为局部变量,引用了new出的对象(80M),作为GC Roots,在Minor GC后被转移到老年代中,且Full GC也不会回收该对象,仍保留在老年代中。

    第二次GC:

    method01方法执行完后,局部变量t跟随方法消失,不再有引用类型指向该对象,该对象在Full GC后,被完全回收,老年代腾出该对象之前所占的空间。

    2.验证方法区中的静态变量引用的对象作为GC Roots

    /**

    * 测试方法区中的静态变量引用的对象作为GCRoots

    * -Xms1024m -Xmx1024m -Xmn512m -XX:+PrintGCDetails

    *

    * 扩展:方法区存与堆一样,是各个线程共享的内存区域,用于存放已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。

    * @author ljl

    * */

    public class TestGCRoots02 {

    private static int _10MB = 10 * 1024 * 1024;

    private byte[] memory;

    private static TestGCRoots02 t;

    public TestGCRoots02(int size) {

    memory = new byte[size];

    }

    public static void main(String[] args) {

    TestGCRoots02 t2 = new TestGCRoots02(4 * _10MB);

    t2.t = new TestGCRoots02(8 * _10MB);

    t2 = null;

    System.gc();

    }

    }

    控制台打印日志:

    [GC [PSYoungGen: 138608K->632K(458752K)] 138608K->82552K(983040K), 0.0684508 secs] [Times: user=0.19 sys=0.06, real=0.07 secs]

    [Full GC [PSYoungGen: 632K->0K(458752K)] [ParOldGen: 81920K->82427K(524288K)] 82552K->82427K(983040K) [PSPermGen: 2513K->2512K(21504K)], 0.0162803 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]

    t2被置为null,Minor GC后t2之前引用的对象(40M)被完全回收;t为静态变量,存放于方法区中,引用了对象(80M),在Minor GC后,被转移到老年代中,且在Full GC后,也不会被回收,继续保留在老年代中。

    3.验证方法区中常量引用对象作为GC Roots

    /**

    * 测试常量引用对象作为GCRoots

    * 注意:t修饰符如果只是final会被回收,static final不会被回收,所以static final 才是常量的正确写法

    * -Xms1024m -Xmx1024m -Xmn512m -XX:+PrintGCDetails

    * @author ljl

    */

    public class TestGCRoots03 {

    private static int _10MB = 10 * 1024 * 1024;

    private static final TestGCRoots03 t = new TestGCRoots03(8 * _10MB);

    private byte[] memory;

    public TestGCRoots03(int size) {

    memory = new byte[size];

    }

    public static void main(String[] args) {

    TestGCRoots03 t3 = new TestGCRoots03(4 * _10MB);

    t3 = null;

    System.gc();

    }

    }

    控制台打印日志:

    [GC [PSYoungGen: 138608K->688K(458752K)] 138608K->82608K(983040K), 0.0514407 secs] [Times: user=0.13 sys=0.02, real=0.05 secs]

    [Full GC [PSYoungGen: 688K->0K(458752K)] [ParOldGen: 81920K->82428K(524288K)] 82608K->82428K(983040K) [PSPermGen: 2515K->2514K(21504K)], 0.0153884 secs] [Times: user=0.06 sys=0.00, real=0.01 secs]

    t3被置为null,Minor GC后t3之前引用的对象(40M)被完全回收;t为常量,存放于方法区中,引用了对象(80M),在Minor GC后,被转移到老年代中,且在Full GC后,也不会被回收,继续保留在老年代中。

    4.测试成员变量是否可作为GC Roots

    /**

    * 测试成员变量引用对象是否可作为GCRoots

    * -Xms1024m -Xmx1024m -Xmn512m -XX:+PrintGCDetails

    *

    * @author ljl

    */

    public class TestGCRoots04 {

    private static int _10MB = 10 * 1024 * 1024;

    private TestGCRoots04 t;

    private byte[] memory;

    public TestGCRoots04(int size) {

    memory = new byte[size];

    }

    public static void main(String[] args) {

    TestGCRoots04 t4 = new TestGCRoots04(4 * _10MB);

    t4.t = new TestGCRoots04(8 * _10MB);

    t4 = null;

    System.gc();

    }

    }

    控制台打印日志:

    [GC [PSYoungGen: 138608K->600K(458752K)] 138608K->600K(983040K), 0.0015591 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

    [Full GC [PSYoungGen: 600K->0K(458752K)] [ParOldGen: 0K->507K(524288K)] 600K->507K(983040K) [PSPermGen: 2513K->2512K(21504K)], 0.0144441 secs] [Times: user=0.06 sys=0.00, real=0.02 secs]

    t4被置为null,Minor GC后t4之前引用的对象(40M)被完全回收;t为成员变量,也叫实例变量,不同于类变量(静态变量),前面讲到类变量是存储在方法区中,而成员变量是存储在堆内存的对象中的,和对象共存亡,所以是不能作为GC Roots的,从日志中也可看出t在MinorGC后,跟随t4一起被完全回收。不再占用任何空间。

    以上为一个非常简单的可作为GC Roots的对象的验证,不涉及较复杂的GC Roots引用链,其实作为使用者来讲,我们只要知道,哪些对象是可作为GC Roots的,在实际开发过程中要特别注意这些对象,不要让无谓的大对象消耗了资源,拖累了性能。

    一、名词解释根搜索算法是JVM用来的判断对象是否存活的算法,此算法基本思路为通过一系列的“GC Roots”对象作为起始点,从这些节点往下搜索,当一个对象和GC Roots不可达时,则该对象是无用的,可被回收的。如下图所示:object5、object6、object7虽然互相有关联,但是他们到GC Roots是不可达的,因此他们都可以被回收。

    在java中,可作为GC Roots的对象有:

    1.虚拟机栈(栈帧中的本地变量表)中引用的对象;

    2.方法区中的类静态属性引用的对象;

    3.方法区中常量引用的对象;

    4.本地方法栈中JNI(即一般说的Native方法)中引用的对象

    二、验证以上可作为GC Roots的对象(此处只做最简单的验证,不涉及很复杂的GCRoots引用链)。

    1.验证虚拟机栈(栈帧中的局部变量)中引用的对象 作为GC Roots

    /** * GCRoots 测试:虚拟机栈(栈帧中的局部变量)中引用的对象作为GCRoots  * -Xms1024m -Xmx1024m -Xmn512m -XX:+PrintGCDetails *  * 扩展:虚拟机栈中存放了编译器可知的八种基本数据类型,对象引用,returnAddress类型(指向了一条字节码指令的地址) * @author ljl */public class TestGCRoots01 {private int _10MB = 10 * 1024 * 1024;private byte[] memory = new byte[8 * _10MB]; public static void main(String[] args) {method01();System.out.println("返回main方法");System.gc();System.out.println("第二次GC完成");} public static void method01() {TestGCRoots01 t = new TestGCRoots01();System.gc();System.out.println("第一次GC完成");}}

    控制台打印日志:[GC [PSYoungGen: 105513K->616K(458752K)] 105513K->82536K(983040K), 0.0945986 secs] [Times: user=0.17 sys=0.06, real=0.09 secs] [Full GC [PSYoungGen: 616K->0K(458752K)] [ParOldGen: 81920K->82430K(524288K)] 82536K->82430K(983040K) [PSPermGen: 2547K->2546K(21504K)], 0.0273364 secs] [Times: user=0.06 sys=0.01, real=0.03 secs] 第一次GC完成返回main方法[GC [PSYoungGen: 15728K->64K(458752K)] 98159K->82494K(983040K), 0.0014739 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC [PSYoungGen: 64K->0K(458752K)] [ParOldGen: 82430K->510K(524288K)] 82494K->510K(983040K) [PSPermGen: 2546K->2546K(21504K)], 0.0118484 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 第二次GC完成第一次GC:

    t为局部变量,引用了new出的对象(80M),作为GC Roots,在Minor GC后被转移到老年代中,且Full GC也不会回收该对象,仍保留在老年代中。

    第二次GC:

    method01方法执行完后,局部变量t跟随方法消失,不再有引用类型指向该对象,该对象在Full GC后,被完全回收,老年代腾出该对象之前所占的空间。

    2.验证方法区中的静态变量引用的对象作为GC Roots

    /** * 测试方法区中的静态变量引用的对象作为GCRoots * -Xms1024m -Xmx1024m -Xmn512m -XX:+PrintGCDetails *  * 扩展:方法区存与堆一样,是各个线程共享的内存区域,用于存放已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。 * @author ljl * */public class TestGCRoots02 {private static int _10MB = 10 * 1024 * 1024;private byte[] memory; private static TestGCRoots02 t; public TestGCRoots02(int size) {memory = new byte[size];} public static void main(String[] args) {TestGCRoots02 t2 = new TestGCRoots02(4 * _10MB);t2.t = new TestGCRoots02(8 * _10MB);t2 = null;System.gc();}}

    控制台打印日志:[GC [PSYoungGen: 138608K->632K(458752K)] 138608K->82552K(983040K), 0.0684508 secs] [Times: user=0.19 sys=0.06, real=0.07 secs] [Full GC [PSYoungGen: 632K->0K(458752K)] [ParOldGen: 81920K->82427K(524288K)] 82552K->82427K(983040K) [PSPermGen: 2513K->2512K(21504K)], 0.0162803 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]

    t2被置为null,Minor GC后t2之前引用的对象(40M)被完全回收;t为静态变量,存放于方法区中,引用了对象(80M),在Minor GC后,被转移到老年代中,且在Full GC后,也不会被回收,继续保留在老年代中。

    3.验证方法区中常量引用对象作为GC Roots

    /** * 测试常量引用对象作为GCRoots  * 注意:t修饰符如果只是final会被回收,static final不会被回收,所以static final 才是常量的正确写法 * -Xms1024m -Xmx1024m -Xmn512m -XX:+PrintGCDetails * @author ljl */public class TestGCRoots03 {private static int _10MB = 10 * 1024 * 1024;private static final TestGCRoots03 t = new TestGCRoots03(8 * _10MB);private byte[] memory; public TestGCRoots03(int size) {memory = new byte[size];} public static void main(String[] args) {TestGCRoots03 t3 = new TestGCRoots03(4 * _10MB);t3 = null;System.gc();}}

    控制台打印日志:[GC [PSYoungGen: 138608K->688K(458752K)] 138608K->82608K(983040K), 0.0514407 secs] [Times: user=0.13 sys=0.02, real=0.05 secs] [Full GC [PSYoungGen: 688K->0K(458752K)] [ParOldGen: 81920K->82428K(524288K)] 82608K->82428K(983040K) [PSPermGen: 2515K->2514K(21504K)], 0.0153884 secs] [Times: user=0.06 sys=0.00, real=0.01 secs]

    t3被置为null,Minor GC后t3之前引用的对象(40M)被完全回收;t为常量,存放于方法区中,引用了对象(80M),在Minor GC后,被转移到老年代中,且在Full GC后,也不会被回收,继续保留在老年代中。

    4.测试成员变量是否可作为GC Roots

    /** * 测试成员变量引用对象是否可作为GCRoots * -Xms1024m -Xmx1024m -Xmn512m -XX:+PrintGCDetails * * @author ljl */public class TestGCRoots04 {private static int _10MB = 10 * 1024 * 1024;private TestGCRoots04 t;private byte[] memory; public TestGCRoots04(int size) {memory = new byte[size];} public static void main(String[] args) {TestGCRoots04 t4 = new TestGCRoots04(4 * _10MB);t4.t = new TestGCRoots04(8 * _10MB);t4 = null;System.gc();}}

    控制台打印日志:[GC [PSYoungGen: 138608K->600K(458752K)] 138608K->600K(983040K), 0.0015591 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC [PSYoungGen: 600K->0K(458752K)] [ParOldGen: 0K->507K(524288K)] 600K->507K(983040K) [PSPermGen: 2513K->2512K(21504K)], 0.0144441 secs] [Times: user=0.06 sys=0.00, real=0.02 secs]t4被置为null,Minor GC后t4之前引用的对象(40M)被完全回收;t为成员变量,也叫实例变量,不同于类变量(静态变量),前面讲到类变量是存储在方法区中,而成员变量是存储在堆内存的对象中的,和对象共存亡,所以是不能作为GC Roots的,从日志中也可看出t在MinorGC后,跟随t4一起被完全回收。不再占用任何空间。

    以上为一个非常简单的可作为GC Roots的对象的验证,不涉及较复杂的GC Roots引用链,其实作为使用者来讲,我们只要知道,哪些对象是可作为GC Roots的,在实际开发过程中要特别注意这些对象,不要让无谓的大对象消耗了资源,拖累了性能。

    ———————————————— 版权声明:本文为CSDN博主「Etyero」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/u010798968/article/details/72835255

    展开全文
  • 这个算法的基本思路就是通过一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”(Reference Chain),如果某个对象到GC Roots间没有任何...

    当前主流的商用程序语言(Java、C#,上溯至前面提到的古老的Lisp)的内存管理子系统,都是通过可达性分析(Reachability Analysis)算法来判定对象是否存活的。这个算法的基本思路就是通过一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”(Reference Chain),如果某个对象到GC Roots间没有任何引用链相连,或者用图论的话来说就是从GC Roots到这个对象不可达时,则证明此对象是不可能再被使用的。

    如图3-1所示,对象object 5、object 6、object 7虽然互有关联,但是它们到GC Roots是不可达的,因此它们将会被判定为可回收的对象。
    在这里插入图片描述
    在Java技术体系里面,固定可作为GC Roots的对象包括以下几种:

    • 虚拟机栈(栈帧中的本地变量表)中引用的对象,譬如各个线程被调用的方法堆栈中使用到的参数、局部变量、临时变量等。

      关联记忆:例如局部变量存在栈中,当方法执行完后,所有的局部变量就会弹出栈,就会进行回收。反之,在栈内的话,就不可回收。

    • 在方法区中类静态属性引用的对象,譬如Java类的引用类型静态变量。

      关联记忆:静态属性生命期和jvm一致,等价于永远存在。

    • 在方法区中常量引用的对象,譬如字符串常量池(String Table)里的引用。

    • 在本地方法栈中JNI(即通常所说的Native方法)引用的对象。

    • Java虚拟机内部的引用,如基本数据类型对应的Class对象,一些常驻的异常对象(比如NullPointExcepiton、OutOfMemoryError)等,还有系统类加载器。

    • 所有被同步锁(synchronized关键字)持有的对象。

    • 反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。

    除了这些固定的GC Roots集合以外,根据用户所选用的垃圾收集器以及当前回收的内存区域不同,还可以有其他对象“临时性”地加入,共同构成完整GC Roots集合。譬如后文将会提到的分代收集和局部回收(Partial GC),如果只针对Java堆中某一块区域发起垃圾收集时(如最典型的只针对新生代的垃圾收集),必须考虑到内存区域是虚拟机自己的实现细节(在用户视角里任何内存区域都是不可见的),更不是孤立封闭的,所以某个区域里的对象完全有可能被位于堆中其他区域的对象所引用,这时候就需要将这些关联区域的对象也一并加入GC Roots集合中去,才能保证可达性分析的正确性。

    目前最新的几款垃圾收集器[1]无一例外都具备了局部回收的特征,为了避免GC Roots包含过多对象而过度膨胀,它们在实现上也做出了各种优化处理。关于这些概念、优化技巧以及各种不同收集器实现等内容,都将在本章后续内容中一一介绍。

    展开全文
  • JVM之GCRoots概述

    2022-04-04 14:03:12
    JVM之GCRoots详解 目录 面试题引子 什么是垃圾 判断对象是否可以被回收之引用计数法 判断对象是否可以被回收之枚举根节点可达性分析 Java中可以作为GC Roots的对象 1. 面试题引子 一面:GC Roots如何确定?...

    JVM之GCRoots详解


    目录

    1. 面试题引子
    2. 什么是垃圾
    3. 判断对象是否可以被回收之引用计数法
    4. 判断对象是否可以被回收之枚举根节点可达性分析
    5. Java中可以作为GC Roots的对象

    1. 面试题引子


    1. 一面:GC Roots如何确定?哪些对象可以作为GC Roots?

    2. 什么是垃圾


    1.简单说就是内存中已经不再被使用到的空间就是垃圾

    3. 判断对象是否可以被回收之引用计数法


    1. Java中,引用和对象是有关联的。如果要操作对象则必须用引用进行。
      因此,很显然一个简单的办法是通过引用计数来判断一个对象是否可以回收。简单说,给对象中添加一个引用计数器,每当有一个地方引用它,计数器值加1,每当有一个引用失效时,计数器值减1。

    2. 任何时刻计数器值为零的对象就是不可能再被使用的,那么这个对象就是可回收对象。

    3. 那为什么主流的Java虚拟机里面都没有选用这种算法呢?其中最主要的原因是它很难解决对象之间相互循环引用的问题。
      在这里插入图片描述


    4. 判断对象是否可以被回收之枚举根节点可达性分析


    1. 为了解决引用计数法的循环引用问题,Java使用了可达性分析的方法。
    2. 所谓"GCroots,或者说tracingGC的“根集合”就是一组必须活跃的引用。
    3. 基本思路就是通过一系列名为”GCRoots”的对象作为起始点,从这个被称为GC Roots的对象开始向下搜索,如果一个对象到GCRoots没有任何引用链相连时,则说明此对象不可用。也即给定一个集合的引用作为根出发,通过引用关系遍历对象图,能被遍历到的(可到达的)对象就被判定为存活,没有被遍历到的就自然被判定为死亡。
      在这里插入图片描述

    在这里插入图片描述


    5. Java中可以作为GC Roots的对象


    1. 虚拟机栈(栈帧中的本地变量表)中引用的对象
    2. 方法区中类静态属性引用的对象
    3. 方法区中常量引用的对象
    4. 本地方法栈中JNI(即一般说的native方法)中引用的对象
    展开全文
  • GC Roots引用

    2021-12-17 08:56:00
    这个算法的基本思路是通过一系列称为”GC Roots"的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”,如果某个对象到GC Roots之间没有任何引用链相连,则证明此...
  • JVM之GCRoots详解

    2021-03-08 08:55:41
    JVM之GCRoots详解目录面试题引子什么是垃圾判断对象是否可以被回收之引用计数法判断对象是否可以被回收之枚举根节点可达性分析Java中可以作为GC Roots的对象1. 面试题引子一面:GC Roots如何确定?哪些对象可以作为...
  • JVM的GC ROOTS有哪些?

    2022-03-24 14:52:12
    可达性分析算法是从GC ROOTS扫描对象引用链,来筛选出有用的对象,扫面完成后,回收掉无用的对象。 JVM的GC ROOTS有哪几个地方呢? a. java虚拟机栈中的引用的对象。 b.方法区中的类静态属性引用的对象。 (一般指被...
  • JVM--可作为GC Roots的对象

    多人点赞 2022-02-05 11:06:32
    本文介绍可作为GC Roots的对象有哪些。 对象是否要回收? 判断对象是否要回收有两种方法:引用计数算法、可达性分析算法。JVM是通过可达性分析算法来判断的。 引用计数算法 给对象中添加一个引用计数器。每当有...
  • 可作为GC Roots的对象

    2020-12-23 14:29:34
    根搜索算法是JVM用来的判断对象是否存活的算法,此算法基本思路为通过一系列的“GC Roots”对象作为起始点,从这些节点往下搜索,当一个对象和GC Roots不可达时,则该对象是无用的,可被回收的。如下图所示:object5...
  • JVM垃圾回收—GC Roots

    2021-09-05 17:25:30
    3、哪些可以作为GC Root 4、GC常用的算法 1)标记清除算法(标记-清除) 2)复制算法 (标记-复制-清除) 3)标记压缩算法(标记-清理-压缩) 1、什么是垃圾 简单的说就是内存中已经不再被使用的空间就是垃圾 ...
  • 一个原因在于GC Roots对象相对于堆中的对象来说,数量相对较少,其次主要的原因还是在于JVM对这一步骤进行了一系列的优化,下面我们就看看JVM在这一步骤中进行的两种优化: 四、JVM 对 GC Roots 根对象枚举过程的...
  • JVM -- GC Roots

    2020-10-26 20:23:09
    JVM – GC Roots 在Java语言中,GC Roots 包含以下以下几类元素: 虚拟机栈中引用的对象     ✔比如:各个线程被调用的方法中使用到的参数、局部变量等 本地方法栈被JNI(通常的说法)引用...
  • gc roots

    2021-07-26 21:36:44
    gc roots ## 什么是 gc roots 可达性分析算法中的起点。 可达性分析算法:通过GC Root 找出所有存活的对象,那么剩下所有的没有标记的对象就是需要回收的对象。 常说的GC(Garbage Collector) Roots,特指的是垃圾...
  • 是否知道什么是GC Roots 什么是垃圾 简单来说就是内存中已经不再被使用的空间就是垃圾 如何判断一个对象是否可以被回收 引用计数法 Java中,引用和对象是有关联的。如果要操作对象则必须用引用进行。 因此,很显然一...
  • 这个算法的基本思路就是通过一系列名为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,下...
  • 通过一系列名为”GCRoots”的对象作为起始点,从这个节点向下搜索,搜索走过的路径称为ReferenceChain,当一个对象到GCRoots没有任何ReferenceChain相连时,(图论:这个对象不可到达),则证明这个对象不可用。
  • GCROOTs详解

    2020-06-07 00:57:07
    2.枚举根节点做可达性分析:也就是有一个GCRoots对象作为根节点,然后做可达性分析,从这个对象向下搜索,如果一个对象到GCroots没有任何引用链相连,则说明该对象不可用。 那些可以作为GCroots根对象: 1....
  • 目录 安装 ​查看gcroots 安装 1.建议装Jprofiler 11 2.idea装插件,直接搜索Jprofiler 3.启动 查看gcroots
  • 我们知道大多数的垃圾收集器在在收集垃圾的时候会停顿所有的线程(Stop The World)来进行可达性分析,那么如何快速找到GC Roots?线程应该在什么地方停止呢?一、快速找到GC ROOTS:OopMap当所有线程停下来的时候,并不...
  • GC ROOTS 包括哪些?

    2021-01-24 11:54:57
    在虚拟机栈中引用的对象 方法区中类静态属性引用的对象 方法区中常量引用的对象 本地方法栈中JNI引用的对象 Java虚拟机内部的引用,如基本数据类型对应的class对象等 所有被同步锁(synchronized 关键字)持有的对象...
  • Java中哪些可以作为GC Roots

    千次阅读 2020-07-20 17:12:00
    方法区、栈和本地方法区不被GC所管理,因而选择这些区域内的对象作为GC roots,被GC roots引用的对象不被GC回收。 根搜索算法是JVM用来的判断对象是否存活的算法,此算法基本思路为通过一系列的“GC Roots”对象作为...
  • 关于gc roots的理解

    2020-02-18 12:57:48
    gc roots是什么 所谓“GC roots”,或者说tracing GC的“根集合”,就是一组必须活跃的引用。 例如说,这些引用可能包括: 所有Java线程当前活跃的栈帧里指向GC堆里的对象的引用;换句话说,当前所有正在被调用的...
  • Java中GCRoots包括哪些

    千次阅读 2020-12-29 07:05:46
    Java中GCRoots包括哪些Java中GCRoots包括哪些GCRoots Java中GCRoots包括哪些 在垃圾回收过程中如何判断一个对象是否是垃圾,有两种算法。一种是引用记数法,一种是可达性分析法。 引用记数法是早期垃圾回收器中使用...
  • 首先那肯定还得是看看概念了,在JVM中,什么可以作为GC Root呢? 虚拟机栈(栈帧中的本地变量表)中引用的对象。  方法区中类静态属性引用的对象。 方法区中常量引用的对象。 本地方法栈中JNI(即一般说的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 34,733
精华内容 13,893
关键字:

gc roots

友情链接: bascules D.zip