JVM-之垃圾回收算法

今天面试菜鸟物流,问到垃圾收集相关问题,因为没做准备(没有想到晚上来电话了,面试官很敬业),脑海的知识都模糊了,答的一踏糊涂,所以还是有必要写下,做个回顾加深下,继续努力,说到JVM的垃圾回收机制,我门首先要明确,垃圾回收主要回收的内存区域是哪里?程序计数器,虚拟机栈,本地方法栈,都是线程私有的,随线程而生随线程而灭,同时栈中栈帧随着方法的进入和退出有条不紊不稳的执行着出栈和入栈操作,每一栈帧分配多少内存是类结构确定下来后就已知的,因此这些区域的内存回收都具备确定性,这几个区域不需要过多的考虑回收的问题,因为方法结束或者线程结束,内存自然就回收了,而Java堆和方法区则不一样,一个接口的多个实现类所需要的内存可能不一样,程序在运行中才会知道创建哪些对象,所以这部分的内存是动态的的分配和动态的回收。

如何判断回收的对象已经"死亡"?

垃圾回收之前要确定哪些对象是存活的,哪些是已死的(既不可能再被任何途径引用的对象),所以需要有方法来判断。
1 . 引用计数算法
引用计数算法是在对象中添加一个引用计数器,一个地方引用它,计数加1,引用失效时减1,当计数为0时,则认为它不可能再被使用,这种放方法实现简单,效率也高,通常情况下是可行的,但是存在 问题 ,什么问题 ?循环引用:即 ObjectA.instance =ObjectB 及ObjectB.instance=ObjectA ,出现这种情况,因为他们互相引用,使得引用计数器都不为0,所以使用引用计数就无法回收它们。
2 .可达性分析算法
主流的程序语言都是通过可达性分析来判定对象是否是存活的。那什么是可达性分析?此算法就是通过一系列被称为GC Roots的对象作为起始点,向下搜索,所走过的路径被称为 引用链,当一个对象到 *GC Roots没有任何引用链相连,也就是GCRootsd到这个对象不可达,则证明该对象是不可用的,它们就会被判定为可回收对象。
GC Roots对象可以包括如下几种:1. 虚拟机栈(栈帧中的本地变量表) 中引用的对象 2. 方法区中类静态属性引用的对象 3.方法区常量引用的对象 4.本地方法栈中JNI引用的对象

以上两种算法可见,判定对象是否可回收,都是与 引用 相关,而引用则又可以分为以下四种:
1 . 强引用:程序中最常见的,如 Object a =new Object();只要强引用存在,就不会被回收。
2 . 软引用:还有用,但是非必须的,软引用关联的对象,在发生内存溢出之前,会把这些对象列进回收范围进行第二次回收,如果第二次回收还没有足够的内存,就会发生内存溢出异常。
3 . 弱引用:被弱引用关联的对象,只能坚持到下一次垃圾回收到来之前,,当回收到来时,无论内存是否足够,都会回收掉弱引用关联的对象。
4 .虚引用:它是最弱的一种引用关系,一个对象是否有虚引用,完全不会对它的生存时间构成影响,唯一目的就是该对象被回收时能够收到一个系统通知。

写了这么多,也该说到回收算法了吧!

当对象通过上述的算法判定为可被回收时,那具体的回收算法过程是如何呢?接下来分别说说

1 .标记清除(Mark-Sweep)
标记清除是最基本的算法,后续的算法都是基于此改进的,分为两个阶段:1.标记2.清除 ,首先将需要回收的对象做上标记,标记完成后做统一的回收,这个算法很基础,主要的不足点存在两个;1.标记和清除的过程效率不高,2.是清除后产生大量不连续的内存碎片,碎片过多回到导致后续有大对象分配时没有足够内村空间,而不得不提前触发一次回收。

2 . 复制算法
复制算法时将内存分为大小相等的两块,每次使用其中的一块,这一块用完了,就将还存活的对象复制到另一半内存上去,然后将使用过的那一半整体回收,这样就是对整个半区进行回收,内存分配时也就不用考虑碎片问题,分配时移动指针按序分配内存即可,这种算法简单,高效,但是存在一点 不足,那就是每次只能使用一半内存,占比有点高,其实在现代的商业虚拟机中,这种算法被用来回收新生代,研究表明,新生代中的对象98%是“朝生夕死”,所以无需按1:1划分,将内存划分为一块较大的Ed en空间和两块较小的Survivor空间,每次使用Eden和一块Survivor当回收时,将Eden和Survivor中存活的对象复制到另一块Survivor,最后清理掉已使用的Eden和Survivor,HotSpot虚拟机默认Ed en和Survivor的大小比例时8:1,所以新生代可用内存为整个新生代的90%,但是我们无法保证每次回收后存活的对象内存占比就小于10%,那另一个Survivor内存就不够用了,这时候,就要依靠老年代进行分配担保,就是另一块Survivor不够存放回收剩余的对象时,这些对象直接通道分配担保机制进入老年代。

3 . 标记整理
当对象存活率不高时,复制算法效率较高,反之则效率会变低,这种算法不适用于老年代,所以根据老年代特点,提出了标记-整理算法,标记过程和标记-清除一样,但是后续不是对标记的对象直接进行回收,而是让存活的对象向一边移动,然后直接清除掉端边界以外的内存。

4.分代收集算法
目前商业虚拟机,都是次啊用分代收集,其实分代收集算法,就是根据对象存活的周期不同将内存划分为新生代,老年代,然后分局各个年代的特点,采用以上不同的算法,如,新生代每次收集都有大量对象死去,少量存活,那就适合复制算法,只 需要少量复制成本,即可完成收集。老年代,对象存活率高,没有额外空间对其进行分配担保,所以必须使用标记-清除或者标记整理

以上就是对几种回收算法的思想介绍,具体的算法是体现在不同的垃圾收集器之上,后续再写具体对应的收集器。

推荐参考书籍:深入理解Java虚拟机

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

推荐阅读更多精彩内容