文档章节

垃圾回收算法

s
 sen_ye
发布于 2018/07/16 15:08
字数 1387
阅读 1
收藏 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引擎...

程序员解决师
2018/06/12
0
0
技术晨读_20160217

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

王二狗子11
2018/01/07
0
0
GC垃圾回收算法

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

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

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

serenity
2016/04/05
3
0
JVM调优总结(2):基本垃圾回收算法

来源: pengjiaheng 链接:http://pengjiaheng.iteye.com/blog/520228 可以从不同的的角度去划分垃圾回收算法: 按照基本回收策略分 引用计数(Reference Counting): 比较古老的回收算法。原...

Alson清
2016/09/29
3
0

没有更多内容

加载失败,请刷新页面

加载更多

Spark in action on Kubernetes - Playground搭建与架构浅析

前言 Spark是非常流行的大数据处理引擎,数据科学家们使用Spark以及相关生态的大数据套件完成了大量又丰富场景的数据分析与挖掘。Spark目前已经逐渐成为了业界在数据处理领域的行业标准。但是...

阿里云官方博客
12分钟前
1
0
小白大数据学习路线

学习大数据首先了解大数据技术得板块划分: 数据计算(离线计算):Hadoop、spark 数据计算(实时计算):storm、spartstreaming、flink 其他框架:zookeeper 数据采集:flume、Kafka 数据存...

董黎明
24分钟前
0
0
mariadb 内存占用优化

本文由云+社区发表 作者:工程师小熊 摘要:我们在使用mariadb的时候发现有时候不能启动起来,在使用过程中mariadb占用的内存很大,在这里学习下mariadb与内存相关的配置项,对mariadb进行调...

腾讯云加社区
今天
3
0
spring security 自定义登录认证

spring security 自定义认证登录 1.概要 1.1.简介 spring security是一种基于 Spring AOP 和 Servlet 过滤器的安全框架,以此来管理权限认证等。 1.2.spring security 自定义认证流程 1)认证...

EasyProgramming
今天
1
0
Win下Jenkins-2.138源码编译及填坑笔记

源码编译篇 1、 安装JDK1.8-181,操作系统添加JDK环境变量。Java -version验证一下。 注:Jenkins2.138版本,JDK必须jkd1.8.0-101以上,不支持Java9,Maven必须3.5.3以上。 2、 解压Maven3....

编程SHA
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部