内存分配与回收策略

文章来源: https://juejin.im/post/5c06625c51882525105421c2, 本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

对象的内存分配,基本上就是在堆上分配,对象主要分配在新生代的Eden区上。少数也可能会直接分配在老年代中。

Minor GC 和 Full GC

Minor GC 发生在新生代上,因为新生代对象存活时间很短,因此Minor GC会频繁执行,执行的速度一般也比较快。 Full GC 发生在老年代上,老年代对象存活时间长,因此Full GCh很少执行,执行速度比Minor GC慢10倍以上。

内存分配策略

对象有限在Eden区分配

大多数情况下,对象在新生代 Eden 区分配,当 Eden 区空间不够时,发起 Minor GC。

大对象直接进入老年代

大对象是指需要大量连续内存空间的对象(字符串、数组)。

经常出现大对象会提前触发垃圾收集以获取足够的连续空间分配给大对象。

-XX:PretenureSizeThreshold,大于此值的对象直接在老年代分配,避免在 Eden 区和 Survivor 区之间的大量内存复制。

长期存活的对象进入老年代

为对象定义年龄计数器,对象在 Eden 出生并经过 Minor GC 依然存活,将移动到 Survivor 中,年龄为1,。此后每经过一次Minor GC,年龄就增加 1 岁,增加到一定年龄则移动到老年代中。

-XX:MaxTenuringThreshold 用来定义年龄的阈值。

动态对象年龄判定

虚拟机并不是永远地要求对象的年龄必须达到 MaxTenuringThreshold 才能晋升老年代,如果在 Survivor 中相同年龄所有对象大小的总和大于 Survivor 空间的一半,则年龄大于或等于该年龄的对象可以直接进入老年代,无需等到 MaxTenuringThreshold 中要求的年龄。

空间分配担保

在发生 Minor GC 之前,虚拟机先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果条件成立的话,那么 Minor GC 可以确认是安全的。

如果不成立的话虚拟机会查看 HandlePromotionFailure 设置值是否允许担保失败,如果允许那么就会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次 Minor GC;如果小于,或者 HandlePromotionFailure 设置不允许冒险,那么就要进行一次 Full GC。

新生代使用复制收集算法,使用其中一个Survivor空间作为轮换备份,因此当出现大量对象再Minor GC后仍然存活的情况,就需要老年代进行分配担保,把Survivor无法容纳的对象直接进入老年代。但是老年代进行担保需要有容纳这些对象的剩余空间,因此取之前的平均值与当前老年代的剩余空间进行比较。

Full GC触发条件

对于 Minor GC,其触发条件非常简单,当 Eden 空间满时,就将触发一次 Minor GC。

Full GC的触发条件如下: ####调用 System.gc() 只是建议虚拟机执行 Full GC,但是虚拟机不一定真正去执行。不建议使用这种方式,而是让虚拟机管理内存。 ####老年代空间不足

老年代空间不足的常见场景为前文所讲的大对象直接进入老年代、长期存活的对象进入老年代等。

为了避免以上原因引起的 Full GC,应当尽量不要创建过大的对象以及数组。除此之外,可以通过 -Xmn 虚拟机参数调大新生代的大小,让对象尽量在新生代被回收掉,不进入老年代。还可以通过 -XX:MaxTenuringThreshold 调大对象进入老年代的年龄,让对象在新生代多存活一段时间。

空间分配担保失败

使用复制算法的 Minor GC 需要老年代的内存空间作担保,如果担保失败会执行一次 Full GC。

JDK 1.7 及以前的永久代空间不足

在 JDK 1.7 及以前,HotSpot 虚拟机中的方法区是用永久代实现的,永久代中存放的为一些 Class 的信息、常量、静态变量等数据。

当系统中要加载的类、反射的类和调用的方法较多时,永久代可能会被占满,在未配置为采用 CMS GC 的情况下也会执行 Full GC。如果经过 Full GC 仍然回收不了,那么虚拟机会抛出 java.lang.OutOfMemoryError。

为避免以上原因引起的 Full GC,可采用的方法为增大永久代空间或转为使用 CMS GC。

Concurrent Mode Failure

执行 CMS GC 的过程中同时有对象要放入老年代,而此时老年代空间不足(可能是 GC 过程中浮动垃圾过多导致暂时性的空间不足),便会报 Concurrent Mode Failure 错误,并触发 Full GC。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

为你推荐:

查看所有标签

码农书籍
程序员思维修炼

程序员思维修炼

亨特 (Andy Hunt) / 崔康 / 人民邮电出版社 / 2015-1-1 / CNY 49.00

本书从认知科学、神经学、学习理论和行为理论角度,深入探讨了如何才能具备优秀的学习能力和思考能力,阐述了成为一名专家级程序员的关键要素,具体包括:大脑运行机制简介,如何正确使用和调试大脑,改进学习能力的具体技巧,如何通过自我引导积累经验,控制注意力的方法。为了让读者加深印象,作者还特别设立了一个“实践单元”,其中包括具体的练习和实验,旨在让读者真正掌握所学内容。生命中没有什么是一成不变的,人们需要改变自己的习惯和方法。不论你是程序员、软件公司管理者、技术奇人还是思想家,或者你只是想让自己的大脑更聪明一点儿,所有尝试改变自己的人,请把本书当作改变的开始……

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

URL 编码/解码
URL 编码/解码

URL 编码/解码