JVM10_引用计数法、GCROOT、Finalization机制、复制、标记清除、标记压缩算法、分代收集、增量收集、分区算法(一)

简介: ①. 引用计数法②. 枚举根节点做可达性分析

前言:

(1). 判断对象存活的两种方式(引用计数算法、枚举根节点做可达性分析)

(2). 标记阶段(引用计数法、枚举根节点做可达性分析)

(3). 清除阶段(复制算法、标记清除算法、标记整理(压缩)算法、分代收集、增量收集算法、分区算法)


①. 引用计数法


①. 原理:假设有一个对象A,任何一个对象对A的引用,那么对象A的引用计数器+1,当引用失败时,对象A的引用计数器就-1,如果对象A的计数器的值为0,就说明对象A没有引用了,可以被回收


②. 最大的缺陷:无法解决循环引用的问题,gc永远都清除不了(这也是引用计数法被淘汰的原因)


③. 代码展示:


/**
 * -XX:+PrintGCDetails
 * 证明:java使用的不是引用计数算法
 */
public class RefCountGC {
    //这个成员属性唯一的作用就是占用一点内存
    private byte[] bigSize = new byte[5 * 1024 * 1024];//5MB
    Object reference = null;
    public static void main(String[] args) {
        RefCountGC obj1 = new RefCountGC();
        RefCountGC obj2 = new RefCountGC();
        obj1.reference = obj2;
        obj2.reference = obj1;
        obj1 = null;
        obj2 = null;
        //显式的执行垃圾回收行为
        //这里发生GC,obj1和obj2能否被回收?
        System.gc();
        try {
            Thread.sleep(1000000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


微信图片_20220106151452.png


④. 注意:Java使用的不是引用计数法(Java之所以没有使用引用计数法,是由于不能解决循环引用问题) | (Python使用了是引用计数法)


⑥. Python如何解决循环引用( 扩展了解 )


手动解决:很好理解,就是在合适的时机,解除引用关系


使用弱引用weakref,weakref是Python提供的标准库,旨在解决循环引用(只要发生了回收,弱引用都会被回收)


②. 枚举根节点做可达性分析


①. 基本思路是通过一系列名为"GC Roots"的对象(集合)作为起点,从这个被称为GC ROOTs 的对象开始向下搜索,如果一个对象到GC Roots没有任何引用链相连时,则说明此对象是不可达对象(被回收),否则就是可达对象


微信图片_20220106151531.png

微信图片_20220106151536.png


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


  (1).虚拟机栈(栈帧中的局部变量表)中的引用对象(比如各个线程被调用的方法中使用到的参数、
    局部变量等)
  (2).本地方法栈中JNI(即一般来说native方法)中引用的对象[ 线程中的start方法 ]
  (3).静态属性引用的对象(比如:Java类的引用类型静态变量)
  (4).方法区中常量引用的对象(比如:字符串常量池(String Table)里的引用)
  (5).所有被synchronized持有的对象
  (6).Java虚拟机内部的引用(基本数据类型对应的Class对象,一些常驻的异常对象
  [如NullPointerException、OutofMemoryError],系统类加载器)
  (7).反映java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等
  (8).注意:除了这些固定的GC Roots集合之外,根据用户所选用的垃圾收集器以及当前回收的内存区域
不同,还可以有其他对象临时加入,共同构架完成整GC Roots集合。比如:分代收集和局部回收(面试加分项)


③. 关于GCroot对象集合 注意事项:


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


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


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


微信图片_20220106151615.png


⑤. 优势:


相对于引用计数法而言,可达性分析算法不仅同样具备实现简单和执行高效 等特点,更重要的是该算法可以有效解决在引用计数算法中循环引用的问题,防止内存泄漏的发生


相较于引用计数算法,这里的可达性分析就是Java、C#选择的。这种类型的垃圾收集通常也叫做追踪性垃圾收集


⑥. 可达性分析算法的 注意事项:如果要使用可达性分析算法来判断内存是否可回收,


那么分析工作必须在 一个能保障一致性的快照中进行。这点不满足的话分析结果的准确


性就无法保证。这点也是导致GC进行时必须“StopTheWorld"的一个重要原因。


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


相关文章
|
2月前
|
算法 JavaScript Java
【状态压缩】【动态规划】【C++算法】1125.最小的必要团队
【状态压缩】【动态规划】【C++算法】1125.最小的必要团队
|
2月前
|
算法 测试技术 C++
【动态规划】【状态压缩】【C++算法】1815 得到新鲜甜甜圈的最多组数
【动态规划】【状态压缩】【C++算法】1815 得到新鲜甜甜圈的最多组数
|
3月前
|
算法 测试技术 C#
【状态压缩】【动态规划】【C++算法】691贴纸拼词
【状态压缩】【动态规划】【C++算法】691贴纸拼词
|
1月前
|
算法 Java UED
【JVM】分代收集算法:提升Java垃圾回收效率
【JVM】分代收集算法:提升Java垃圾回收效率
19 0
|
2月前
|
算法 测试技术 C++
【状态压缩】【动态规划】【C++算法】691贴纸拼词
【状态压缩】【动态规划】【C++算法】691贴纸拼词
|
2月前
|
存储 缓存 安全
深入理解JVM - Hotspot算法细节
深入理解JVM - Hotspot算法细节
36 0
|
3月前
|
SQL 存储 编解码
Hive中的压缩技术是如何实现的?请解释其原理和常用压缩算法。
Hive中的压缩技术是如何实现的?请解释其原理和常用压缩算法。
27 0
|
1月前
|
机器学习/深度学习 算法 生物认证
基于深度学习的人员指纹身份识别算法matlab仿真
基于深度学习的人员指纹身份识别算法matlab仿真
|
26天前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到"hand.txt"文件。
|
1月前
|
机器学习/深度学习 算法 计算机视觉
基于yolov2深度学习网络的视频手部检测算法matlab仿真
基于yolov2深度学习网络的视频手部检测算法matlab仿真