良许Linux教程网 干货合集 详解JVM垃圾回收的算法

详解JVM垃圾回收的算法

JVM 会自动帮程序员进行垃圾回收,并不需要程序员手动的进行垃圾回收(C++等语言需要自己手动回收垃圾),了解 JVM 的垃圾回收,可以帮程序员写出占用内存更小、更高效的程序。

标记-清除

顾名思义,其过程分为两个阶段,分别是标记清除。首先标记出所有需要回收的对象,然后统一对标记的对象进行回收。这个算法的十分的局限,首先标记和清除的两个过程效率都不高,而且这样的清理方式会产生大量的内存碎片,什么意思呢?

就是虽然总体看起来还有足够的剩余内存空间,但是他们都是以一块很小的内存分散在各个地方。如果此时需要为一个大对象申请空间,即使总体上的内存空间足够,但是JVM无法找到一块这么大的连续内存空间,就会导致触发一次GC。

聊一下JVM是如何进行垃圾回收的算法聊一下JVM是如何进行垃圾回收的算法

复制

其大致的思路是,将现有的内存空间分为两半A和B,所有的新对象的内存都在A中分配,然后当A用完了之后,就开始对象存活判断,将A中还存活的对象复制到B去,然后一次性将A中的内存空间回收掉。

聊一下JVM是如何进行垃圾回收的算法聊一下JVM是如何进行垃圾回收的算法

这样一来就不会出现使用标记-清除所造成的内存碎片的问题了。但是,它仍然有自己的不足。那就是以内存空间缩小了一半为代价,而在某些情况下,这种代价其实是很高的。堆中新生代就是采用的复制算法。刚刚提到过,新生代被分为了Eden、From Survivor、To Survivor,由于几乎所有的新对象都会在这里分配内存,所以Eden区比Survivor区要大很多。因此Eden区和Survivor区就不需要按照复制算法默认的1:1的来分配内存。在HotSpot中Eden和Survivor的比例默认是8:1,也就意味着只有10%的空间会被浪费掉。

看到这你可能会发现一个问题。既然你的Eden区要比Survivor区大这么多,要是一次GC之后的存活对象的大小大于Survivor区的总大小该怎么处理?的确,在新生代GC时,最坏的情况就是Eden区的所有对象都是存活的,那这个JVM会怎么处理呢?这里需要引入一个概念叫做内存分配担保。当发生了上面这种情况,新生代需要老年代的内存空间来做担保,把Survivor存放不下的对象直接存进老年代中。

标记-整理

标记-整理其GC的过程与标记-清楚是一样的,只不过会让所有的存活对象往同一边移动,这样一来就不会像标记-整理那样留下大量的内存碎片。

聊一下JVM是如何进行垃圾回收的算法聊一下JVM是如何进行垃圾回收的算法

分代收集

这也是当前主流虚拟机所采用的算法,其实就是针对不同的内存区域的特性,使用上面提到过的不同的算法。

例如新生代的特性是大部分的对象都是需要被回收掉的,只有少量对象会存活下来。所以新生代一般都是采用复制算法

而老年代属于对象存活率都很高的内存空间,则采用标记-清除标记-整理算法来进行垃圾回收。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部