JVM垃圾回收时如何确定垃圾?是否知道什么是GCRoots?
垃圾回收算法
- 引用计数法
- 可达性分析
什么是垃圾?
简单地说就是内存中已经不再被使用到的空间就是垃圾
要进行垃圾回收,如何判断一个对象是否可以被回收
程序计数器、虚拟机栈、本地方法栈。这几个区域完全不用管回收问题,因为方法结束或者线程结束的时候他们所占用的内存就自然跟着一起释放了,3个区域随线程而生,随线程而灭。所以我们只需要管堆和方法区。
- 引用计数法 - 循环引用问题,为了解决引入以下2方法
给对象中添加一个引用计数器,每当有一个地方引用他时,计数器值就+1,;当引用失效时,计数器值就-1;任何时刻计数器为0的对象就是不可能在被使用。分析上述代码
很明显,到最后两个实例都不再用了(都等于null了),但是GC却无法回收,因为引用数不是0,而是1,这就造成了内存泄漏。也很明显,现在虚拟机都不采用此方式。
- 枚举根节点做可达性分析(根搜索路径)
可达性分析
https://img2018.cnblogs.com/blog/987988/201908/987988-20190828143350163-1357935534.png
https://upload-images.jianshu.io/upload_images/3614577-df363843c09c826b.png?imageMogr2/auto-orient/strip|imageView2/2/format/webp 基本思路就是通过一系列名为GC Roots的对象作为起始点,向下搜索,搜索所走过的路径称为引用链,如果一个对象到GC Roots没有任何引用链相连时,则说明此对象不可用
什么是GC Roots呢?
就是一组必须活跃的引用
哪些对象可以作为GC Roots呢?
- 虚拟机栈(栈帧中的本地变量表)中引用的对象
- 方法区中的类静态属性引用或者常量引用的对象
- 本地方法栈JNI(就是native方法)中引用的对象