博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
垃圾回收算法
阅读量:6033 次
发布时间:2019-06-20

本文共 1659 字,大约阅读时间需要 5 分钟。

hot3.png

一 如何判断对象可以回收

1 引用计数法

思路大概为:给对象添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时,计数器减1;任何时刻计算器为0的对象就是不可能再被使用的。优点是,实现简单;但是如果两个引用之间相互引用,导致它们的引用计数都不为0的话,无法通知GC收集器回收它们。

2 可达性算法

思路大概为:从一系列可以作为"GC Roots"的对象作为起始点,从这些节点开始往下搜索,搜索走过的路径成为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

可作为"GC Roots"的对象主要包括以下几种:

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

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

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

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

特别提醒,方法区(或者说HotSpot虚拟机中的永久代)也是需要垃圾回收的,虽然java虚拟机规范中确实说过可以不要求虚拟机在方法区中实现垃圾回收,而且在方法区中进行垃圾收集的性价比比较低。永久代的垃圾回收主要包括两部分内容:废弃常量和无用的类。废弃常量回收的一个例子为常量池的字符串的回收。判断一个类是否无用的类比较复杂,必须具备以下三个条件:

1该类的所有实例已被回收,也就是java堆中不存在该类的实例

2加载该类的ClassLoader已经被回收

3该类的java.lang.Class对象没有在任何地方被引用到,无法在任何地方通过反射访问该类的方法

二 垃圾收集算法

1标记清除算法(Mark-Sweep)

核心内容分为标记和清除两个阶段: 首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。它的不足主要有两个:一个是效率问题,标记和清除两个过程的效率都不高;另一个是标记清除后会产生大量不连续的内存碎片,空间碎片太多在以后程序需要分配大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾回收动作。

 

2标记整理(标记压缩 Mark-Compact)算法

标记整理算法的标记阶段和标记清除算法基本一致,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存

 

3复制算法

复制算法将内存按照容量划分为大小相等的两块,每次只使用其中的一块,当这一块的内存用完了,就将还存活的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样可以使得每次都是针对整个半区进行内存回收,内存分配时也不需要考虑内存碎片的问题。不足之处就是讲内存缩小为原来的一半,代价比较高。而且在对象存活率较高时要进行较多的复制操作,效率比较低。

商用的虚拟机一般不是按照1:1的比例划分内存空间,而是将内存划分为一块较大的eden空间和两块较小的Survivor空间,每次使用eden和其中一块survivor。当回收时,把eden和survivor中存活的对象一次性复制到另外一块survivor空间上,最后清理掉eden和刚才使用过的survivor空间。HotSpot默认eden和Survivor的比例为8:1,也就是每次新生代可用内存空间为90%,只有10%会被浪费。需要注意的是我们没有办法保证每次回收都只有不多于10%的对象存活,所以当Survivor空间不足时,需要依赖其他内存(这里指老年代)进行分配分担。虚拟机参数-XX:Surviorratio : 设置Eden和一个Suivior的比例,比如值为5,代表eden占年轻代的空间为5/(5+1+1)=5/7。

总结:

分代收集算法其实是基于上面三个算法,分代收集根据对象存活周期的不同将内存划分为几块。新生代每次垃圾回收都有大批对象死去,所以一般采用复制算法,老年代则因为对象存活率高,没有额外空间为它进行分配担保,就必须采用标记-清理或者标记-整理算法来进行回收。

 

转载于:https://my.oschina.net/leandison/blog/1856166

你可能感兴趣的文章
存储过程中调用webservice
查看>>
神奇语言 python 初识函数
查看>>
Windows安装Composer出现【Composer Security Warning】警告
查看>>
四 指针与数组 五 函数
查看>>
硬盘空间满了
查看>>
dutacm.club Water Problem(矩阵快速幂)
查看>>
深入JVM内核--GC算法和种类
查看>>
iOS的AssetsLibrary框架访问所有相片
查看>>
MySQLdb的安装
查看>>
读书笔记三
查看>>
数论 - 最小乘法逆元
查看>>
企业架构研究总结(22)——TOGAF架构开发方法(ADM)之信息系统架构阶段
查看>>
接口测试(三)--HTTP协议简介
查看>>
周志华《机器学习》课后答案——第4章.决策树
查看>>
frameset分帧问题
查看>>
特殊样式:ime-mode禁汉字,tabindex焦点
查看>>
linux
查看>>
Layout父元素点击不到的解决办法
查看>>
【面试次体验】堆糖前端开发实习生
查看>>
基于apache实现负载均衡调度请求至后端tomcat服务器集群的实现
查看>>