文档章节

垃圾回收算法

s
 sen_ye
发布于 07/16 15:08
字数 1387
阅读 0
收藏 0

一 如何判断对象可以回收

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。

总结:

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

 

© 著作权归作者所有

共有 人打赏支持
s
粉丝 0
博文 9
码字总数 6292
作品 0
广州
javascript 垃圾回收算法了解一下

我们通常理解的 javascript 垃圾回收机制都停留在表面,"会释放不被引用变量内存",最近在读《深入浅出node.js》的书,详细了解了下 v8 垃圾回收的算法,记录了一些学习笔记。 敲黑板:v8引擎...

程序员解决师
06/12
0
0
GC垃圾回收算法

什么是GC垃圾回收呢。日常生活中我们去餐厅吃饭吃完饭,吃完饭走了餐具不用管,服务员在把餐具拿走,这是一种方式,服务员怎么知道他要来把餐具拿走呢,因为你走了,这个位置空了。服务员什么...

分享达人
2016/04/10
0
0
JVM调优总结(2):基本垃圾回收算法

可以从不同的的角度去划分垃圾回收算法: 按照基本回收策略分 引用计数(Reference Counting): 比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。...

serenity
2016/04/05
3
0
技术晨读_20160217

技术导读 Build a RESTful API with Martini 使用martini搭建一个Restful API,使用的是简易的内存database,搭建了一套支持json和xml的RESTFUL的API http://0value.com/build-a-restful-API...

王二狗子11
01/07
0
0
深入理解JVM学习笔记(二十一、JVM 垃圾回收机制---如何回收垃圾---回收策略【标记-清除算法】)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jintaohahahaha/article/details/82696616 标记-清除算法是GC中最基础的算法。从名称上看,其可以拆分为两部分...

张--小涛涛
09/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

软件测试工具书籍与面试题汇总下载(持续更新)

简介 本文是https://github.com/china-testing/python-api-tesing/blob/master/books.md 的节选。 欢迎转载,转载请附带此简介,谢谢! 试题 软件测试综合面试题(高级测试)-试题.pdf 软件测试...

python测试开发人工智能安全
27分钟前
0
0
java.sql.SQLException: Io 异常: The Network Adapter could not establish the connection 解决

有个项目使用的log4j进行日志记录的,同时也是用log4j中的数据库配置直接把相应级别的日志直接插入oracle。 在把项目部署的另一个内网环境时候,把项目的其他配置都改了,唯独log4j中的数据库...

哥本哈根的小哥
37分钟前
1
0
耗时 2 年,用 8.5 万块乐高积木最牛复刻 Apple Park

简评:国外大佬复刻 Apple Park,看了一下细节,确实厉害!只有你想不到,没有乐高拼不起来的,有没有乐高大神挑战一下? 苹果公园以各种各样的方式鼓舞人心,让人感兴趣。从建筑、可持续性和...

极光推送
38分钟前
1
0
记一次查找Hdfs磁盘占用空间比实际存储文件大4倍的原因

在一次主备namenode发生切换后,重启datanode节点,发现磁盘空间很大,想清理一下磁盘, 通过命令Hdfs dfs -du -h --max-depth=1 / 发现实际文件的大小只有8g,通过du -h --max-depth=1 /ha...

PageYi
今天
5
0
阿里云推荐引擎使用教程

产品概述: 推荐引擎(Recommendation Engine,以下简称RecEng,特指阿里云推荐引擎)是在阿里云计算环境下建立的一套推荐服务框架,目标是让广大中小互联网企业能够在这套框架上快速的搭建满...

mcy0425
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部