概述
为新对象分配内存是一个非常严谨和复杂的任务。JVM的设计者们不仅需要考虑内存如何分配、在哪里分配等问题,并且由于内存分配空间算法与内存回收算法密切相关,所以还需要考虑GC执行完内存回收是否会在内存空间中产生内存碎片。
Java对象的分配和回收过程:
- 创建的对象首先被放在Eden区。(此区有大小限制)
- Eden区空间填满时,程序又需要创建对象,JVM的垃圾收集器将会对Eden区进行YoungGC(Minor GC),将Eden区中的不再被其它对象所引用的对象进行销毁。后边再加载进来的新对象依然首选放到Eden区。
- 然后将Eden区中剩余对象移动到Survivor0区
- 如果再次触发YoungGC,此时上次幸存下来的对象将被S0区,如果没有回收,就会放到S1区。
- 如果再次经历垃圾回收,此时会重新放回S0区,接着再去S1区。
- 何时将对象转移到老年代区?可以设置对象的存活周期阈值。默认是15次。
-XX:MaxTenuringThreshold = <N> 进行设置
- 在老年代区,当老年代区内存不足时,触发OldGC(Major GC),进行老年代区的内存清理。
- 如果老年代区执行了MajorGC后,发现依然无法进行对象的保存,就会OOM异常
java.lang.OutOfMemoryErro: Java heap space
小结:
1-针对幸存者S0(From/To)、S1(From/To)区,复制之后有交换,谁空谁是To区
2-关于垃圾回收:对象回收一般频繁会在新生代区收集,很少在老年代区收集,几乎不在永久代/元空间收集。
对象在Heap内存中的分配和回收流程图
前边关于对象在内存中分配过程,可以用下边流程图表示,过程已经很详细了,不再赘述。
内存分配策略(对象晋升Promotion规则)
如果对象的Eden区出生,并经过一次Minor GC后依然存活,并且能够被Survivor区容纳的话,将被移动到Survivor区,并且对象的存活年龄设为1。
对象在Survivor区中每熬过一次MinorGC,存活年龄值就增加1,当它的年龄增加到一定的程度(默认为15岁,每个GC各不相同),就会晋升到老年代中。
对象晋升的阈值可以通过选项 -XX:MaxTenuringThreshold来设置。
针对不同年龄段的对象分配原则如下:
- 新生对象有限被分配到Eden区
- 大对象直接进入到老年代
避免程序中出现较多的大对象。
- 长期存活的对象分配到老年代
- 动态年龄判断
如果survivor区间中相同年龄的所有对象的大小总和大于survivor区间的一半,年龄大于或等于该年龄的对象可以直接进入到老年代区,无需等到MasTenuringThreshold中设置的晋升年龄阈值。
举个栗子:
如对象年龄5的占30%,年龄6的占36%,年龄7的占34%,加入某个年龄段(如例子中的年龄6)后,总占用超过Survivor空间*TargetSurvivorRatio的时候,从该年龄段开始及大于的年龄对象就要进入老年代(即例子中的年龄6对象,就是年龄6和年龄7晋升到老年代),这时候无需等到MaxTenuringThreshold中要求的15。
- 空间分配担保原则
空间分配担保目的:在年轻代进行Minor GC前,老年代本身应该还有容纳新生代所有对象的剩余空间。如果不够,则进行Full GC。
配置参数:-XX:HandlePromotionFailure 是否设置空间分配担保
大对象直接进入老年代栗子:
/**
* 测试大对象直接进入老年代
*
* -Xmx40m -Xms40m -XX:NewRatio=2 -XX:SurvivorRatio=8 -XX:+PrintGCDetails
*/
public class YoungOldAreaDemo {
public static void main(String[] args) {
// 创建一个20m大小的对象
byte[] data = new byte[1024 * 1024 * 20];
}
}
运行前先做一下VM参数配置配置:
控制台输出结果:
因为设置总的堆内存大小只有40m,新生代空间12m,老年代空间27m,新建的20m大对象将直接晋升到老年代区间。
最后
以上就是风趣小蝴蝶为你收集整理的图解Java对象在Heap内存中的分配和回收过程Java对象的分配和回收过程:对象在Heap内存中的分配和回收流程图内存分配策略(对象晋升Promotion规则)的全部内容,希望文章能够帮你解决图解Java对象在Heap内存中的分配和回收过程Java对象的分配和回收过程:对象在Heap内存中的分配和回收流程图内存分配策略(对象晋升Promotion规则)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复