Java虚拟机之垃圾回收算法

1. 垃圾回收器如何确定对象死亡

1.1 引用计数法

实现原理:给对象中添加一个引用计数器,每当有引用它时,计数器就加1,如果引用失效,计数器值就减1,计数器为0的对象就是没有被再使用过的对象。

优点:引用计数算法实现起来较为简单,判定效率也很高。
缺点:无法解决互相循环引用的问题。

1.2 可达性分析算法

实现原理:通过一系列的称为GC Roots的对象作为起始点,当一个对象到GC Roots没有任何引用链(Reference Chain)相连时,则表明此对象不可用

注意:在Java语言中,可作为GC Roots的对象包括下面几种:

虚拟机栈(虚拟机栈中的本地变量表)中引用的对象。
方法区中静态类属性引用的对象
方法区中常量引用的对象
本地方法栈中native方法引用的对象

注意:在可达性分析算法中,并不是不可达的对象一定会被回收,至少要经历两次标记过程:

如果某个对象在进行可达性分析算法之后没有发现和GC Roots的引用链,它会被标记一次并且进行筛选,筛选的条件就是该对象是否有必要执行finalize()方法,当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,虚拟机在这两种情况下都会认为没必要执行

如果一个对象被判定为有必要执行finalize()方法,那么这个对象会被放置在F-Queue队列中,在稍后会由虚拟机建立一个,低优先级的Finalizer线程去执行它,但不会等它结束

最后一次挣扎

finalize()方法是对象逃脱死亡的最后一次机会,稍后GC将会对F-Queue中的对象进行第二次小规模的标记,如果对象要在finalize()方法中进行自救,只需要重新与引用链上任何一个对象建立关联即可。

2. 垃圾回收算法

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

顾名思义,分为标记清除两个阶段:标记出所有需要回收的对象,然后统一回收所有被标记的对象。

缺点:标记和清除的效率都不高,标记清除后会有大量不连续的内存碎片,而过多的内存碎片,会导致后续分配大对象时无法找到足够的连续内存空间,继而触发另一次垃圾回收动作

2.2 复制算法(Copying)

将可用内存分为大小相同两块。每次只用一块,当一块空间用完了,就将还存活的对象复制到另一块上,然后将刚使用过的内存空间一次清理掉。这样使得每次都是对其中的一块进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况。实现简单,运行高效。


优点:算法实现简单,内存效率高,不易产生碎片。
缺点:可用内存被压缩到了原本的一半。且存活对象增多的话,Copying算法的效率会大大降低。

2.3 标记-整理(Mark-Compact)

复制收集算法在对象存活率高的时候就要执行较多的复制操作,效率将会变低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保用于应付半区内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选用这种算法。
原文地址
https://blog.csdn.net/byhook/article/details/83046041
因此人们提出另外一种“标记-整理”(Mark-Compact)算法由于老年代中的对象生存周期都较长,有人提出“标记-整理”算法,标记过程和“标记-清理”一样,但在清除已死对象的同时会对存活对象进行整理,这样可以减少碎片空间。

2.4 分代收集算法

当前商业虚拟机的垃圾收集都是采用分代收集(Generational Collecting)算法,这种算法并没有什么新的思想出现,只是根据对象不同的存活周期将内存划分为几块。一般是把Java堆分作``新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就用复制算法,只要少量复制成本就可以完成收集。而老年代中因为对象的存活率较高、周期长,就用标记-整理标记-清除算法来回收。

新生代复制回收机制

将新生代区域分为EdenFrom SurvivorTo Survivor,比例为8:1:1

实现原理
a. Eden区域最大,对外提供堆内存,当Eden区快满的时候,进行Minor GC,把存活对象放入From Survivor区域,然后清空Eden区域,移动之后会标记相应的age为1,这样就 完成了一次Minor GC
b. 由于Eden区域被清空,对外提供堆内存,当Eden区域又快满的时候,就会再次触发Minor GC,将Eden区域和From Survivor区域中存活的对象复制到To Survivor区域中,然后将Eden以及From Survivor区域清空,标记从Eden复制到To Survivor区域中的对象年龄设置为1,再将从From Survivor区域中复制过去的对象年龄+1,这样完成了第二次GC
c. 同上,当Eden区域再次快满的时候,就会将Eden区域以及To Survivor区域中的存活对象,复制到From Survivor区域中,标记从Eden复制到From Survivor区域中的对象年龄设置为1,再将从To Survivor区域中复制过去的对象年龄+1,这样完成了第三次GC
d. ......后面的步骤跟之前的b、c步骤交替进行
e. 当一个存活对象的年龄熬过一定次数之后(默认为15次),该对象就会被移动到老年代。

老年代-标记整理回收机制

老年代一般存放的是存活时间较久的对象,所以每一次 GC 时,存活对象比较较大,也就是说每次只有少部分对象被回收。
因此,根据不同回收机制的特点,这里选择 存活对象多,垃圾少 的标记整理 回收机制,仅仅通过少量地移动对象就能清理垃圾,而且不存在内存碎片化。

3 垃圾收集器

如果说垃圾收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。

3.1 Serial收集器

缺点:它在进行垃圾回收的时候,必须暂停所有的工作线程。

3.2 ParNew收集器

它是Serial收集器的多线程版本,用于新生代内存回收,可以配合CMS使用

3.3 Parallel Scavenge收集器

它是一个新生代收集器,也是使用复制算法的收集器,它的目标是达到一个可控制的吞吐量。

3.4 Serial Old收集器

他是Serial收集器的老年代版本,使用的是标记整理算法。

3.5 Parallel Old收集器

他是Parallel Scavenge收集器老年代版本,使用的是标记整理和多线程。

3.6 CMS收集器

它是一种以获取最短停顿时间为目标的收集器。基于标记-清除算法实现的,整个过程如下:
初始标记(CMS initial mark)
并发标记(CMS concurent mark)
重新标记(CMS remark)
并发清除(CMS initial sweep)
其中初始标记重新标记依然需要暂停工作线程。

优点:并发手机,停顿低。

原文地址
https://blog.csdn.net/byhook/article/details/83046041
参考:
《深入理解Java虚拟机》

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