2018-01-08 JVM篇之 GC算法


–引用计数法

是一个老牌垃圾回收算法,通过引用计算来标记,判断一个对象是不是垃圾,是不是要回收。

基本思想 : 为每一个对象都标记一个引用数量,引用计数器的实现很简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,当引用失效时,引用计数器就减1。只要对象A的引用计数器的值为0,则对象A就不可能再被使用。

对于上图,根对象和ABC三个对象,有互相引用的关系,ABC引用计数分别为1

当A对B的引用失去之后,B的引用变成了0,根据引用计数的规则,引用为0 的B对象就会当作垃圾回收掉,回收之后堆中只剩下根对象和AC。

引用计数法带来的问题

1、引用和去引用伴随加法和减法,,因为要实时的计算当前对象有多少个引用,对象的引用和消是无时无刻存在的,所以对影响有一定性能

2、很难处理循环引用的问题,看下面的问题,

上图中,根对象引用A,引用C,C引用B,B又引用A,所以引用计算A(2),C(1),B(1),当,根对象失去对A的引用时,由于A,B,C三者互相引用,所以三个对象的引用计数都是1,所以A,B,C相当于一个独立体,无法被回收,如果堆中存在大量这样的无用对象,就会导致不停的GC,而GC后又无效果,最终内存溢出

–标记清除

        标记-清除算法是现代垃圾回收算法的思想基础。    

        基本思想:标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段。一种可行的实现是,在标记阶段,首先通过根节点做搜索,标记所有从根节点开始的可达对象。因此,未被标记的对象就是未被引用的垃圾对象。然后,在清除阶段,清除所有未被标记的对象。

在标记清除算法中,大致总结思路如下:从根节点开始做两件事情

1、标活(标记可达对象),标记A,B,C,D,E是可达对象

2、去死 (去除不可达对象),去除黑色区域不可达对象

通过上面图可以反应出,从堆中清空垃圾对象后,堆中的可用空间比较分散不连续,这时候如果有一个大的对象需要申请6个连续的空间,是无法分配,会造成大量的空间碎片。标记压缩算法可以避免这种情况的发生。

–标记压缩

基本思路:在标记-清除算法的基础上做了一些优化。和标记-清除算法一样,标记-压缩算法也首先需要从根节点开始,对所有可达对象做一次标记。但之后,它并不简单的清理未标记的对象,而是将所有的存活对象压缩到内存的一端。之后,清理边界外所有的空间。

执行过程如下图:

标记压缩

大致总结思路如下:从根节点开始做两件事情

1、标活

2、移动存活对象到一端

3、清除边界外的所有空间

标记压缩对标记清除而言,有什么优势呢?

相比与标记清除算法,清理之后,会有大量的连续空间,不会有空间碎片,标记-压缩算法适合用于存活对象较多的场合,如老年代。

–复制算法

基本思想 :将原有的内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收

复制算法两空一样大小的空间,下面是复制算法的执行过程:

复制算法

1、标活

2、复制存活对象从FROM区域到TO区域

3、交换FROM与TO的角色

与标记-清除算法相比,复制算法是一种相对高效的回收方法,在现在的JVM中,复制算法一般会用于年轻代,但是复制算法的最大问题是:空间浪费,每次只使用一半的空间。

可以想想,比如为复制算法分配8G的空间,但是在使用过程中会浪费4G的空间,当然8G的复制空间也只是举个例子,为了更能突出空间的浪费 ,因为复制算法本身的特性决定 ,是需要将存活对象进行一次复制 ,所以复制空间一般都不会很大,因为大的空间,如果在极端情况下,会涉及大量存活对象的移动,这种大量的移动对于系统本身,无疑问是灾难性的。

在现在的JVM中也不会很大,每一块复制区域默认占用1/10的空间。比如,有10M的空间默认的,FROM和TO区域分别占用1M。

所以一般整合标记清理思想,对复制算法会做一些改进,如下图:

复制算法改进

因为复制空间越大,浪费的空间越大,复制算法空间一般不会很大,一般在复制过程 中会了现两种情况

第一种:对象太大,放不到复制空间

第二种:即使大对象放得下,也会导致大量的小对象无法存放,会导致大量的不符合老年代特性的小对象进行老年代

所以复制算法一般需要一个担保空间,如上图中蓝色区域。

比如:C、D、F是大对象,在一执行复制算法后,会直接进入到担保空间。

对于对JVM堆内存划分有了解的人,可能对上面的图比较熟悉,这其实已经很接近JVM堆空间的结构,蓝色区域复制算法的担保空间就我们经常说的老年代(Old Generation)。顶部的区域就是年轻代(Eden),而中间两块复制算法的空间就是幸存区(Surivor),对比上面和下面的图,发现是完全可以吻合的。

JVM堆内存划分

分代思想

依据对象的存活周期进行分类

第一类:有些对象创建后,很快就会回收,我们把短命对象归为新生代,

第二类:有些对象创建后会长期存在,有可能和JVM生命周期相同,我们把长命对象归为老年代。

根据不同代的特点,选取合适的收集算法

–少量对象存活,适合复制算法

–老年代中的对象有两种:

         老年代中的对象:多次GC没有回收掉,年龄校大的对象,生命周期较长

         复制算法空间担保 ,直接进入 老年代的大对象

所以会有大量对象存活,和大对象,适合标记清理或者标记压缩


所有的算法,需要能够识别一个垃圾对象,因此需要给出一个可触及性的定义

什么是可触及的:从根节点可以到达的对象,此对象称为可触及的

可复活的: 一旦所有引用被释放,就是可复活状态(因为在finalize()中可能复活该对象)

什么是不可触及的:在finalize()后,可能会进入不可触及状态,不可触及的对象不可能复活,不可触及的对象,是可以回收的


上面的算法中,我们一直说从根节点查找,都提到了根节点,所以我们要搞清楚什么是根节点?

–栈中引用的对象(局部变量表)

–方法区中静态成员或者常量引用的对象(全局对象)

–JNI方法栈中引用对象

根是一系列对象的集合,是一砣根节点,文章中为了简单所以只有一个根对象,希望不要给大家带来误解!

GC中的一个重要 的现象Stop-The-Word

java中一种全局暂停的现象,所有的JAVA代码停止 ,native代码可能执行,但不能和JVM交互

引起STW的原因 :GC 、DUMP线程、堆 DUMP

多半是因为GC引起的。

为什么会产生全局停顿?

GC需要一个安静的状态来完成垃圾的回收,所以需要将用户线程停止,完成垃圾回收后,再继续用户线程。

STW危害?

1、影响系统吞吐量,系统响应时间 增长

2、长时间的服务停止,没有响应,遇到HA系统,可能引起主备切换,最终导致主备同时启动。在一些业务场景下,可能会导致数据不致,甚至无法正常工作。

大家好我是BK,第一次写文章 ,写和不是很好,有错误的地方,请大家指正,谢谢大家!

后续会更新GC的种类和各类的区别。希望大家可以关注我。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345