JVM内存分配和垃圾回收策略

内存分配和回收策略

Java技术体系所倡导的自动管理内存解决了两个问题:

(1)给对象分配内存

(2)回收分配给对象的内存


对象内存的分配主要在Eden区上,少数会在老年代中。

(1)对象有优先分在Eden区上

     大多数情况下对象优先分配在Eden区上,当Eden区上没有足够空间进行分配的时候将发起一次MinorGC;

(2)大对象直接进入老年代

大对象是指需要大量连续内存空间的java对象,最典型的大对象是指那种很长的字符串以及数组,经常遇到大对象会导致还有不少空间就提前出发垃圾回收以获取足够的连续空间来“安置”他们。

(3)长期存活的对象将进入年老代

Java虚拟机采用了分代收集的思想来管理内存,那么内存回收的时候就必须能够识别哪些对象应该放在新生代,哪些对象应该放在老年代。为了做到这一点,虚拟机给每个对象定义了一个对象年龄计数器。

1)如果对象在Eden区出生并经过一次Minor GC后仍然存活,并且能被Survivor容纳,那么就会被移动到Survivor空间中,并且对象的年龄设置为1

2)对象在Survivor空间中每经过一次Minor GC仍然存活,年龄就加一岁,默认15岁以后进入老年代。

(4)动态年龄判定

为了能更好地适应不同程序的内存状况,虚拟机并不会永远要求对象的年龄必须到达MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄的对象占用的空间大于Survivor空间的一半,那么大于等于这个年龄的对象会进入老年代中。

(5)空间分配担保

在发生Minor GC之前,虚拟机先检查老年代最大可用的连续空间是否大于新生代中所有对象的内存之和,如果大于,直接进行内存回收,可以确保Minor GC是安全的,如果小于则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。

1)允许担保失败,则会查看以往每次年轻代晋升到老年代中对象容量的平均值和现在老年代中的内存对比,如果老年代内存大于这个平均值,则进行Minor GC

2)如果不允许担保失败或者老年代中内存小于平均值那么进行Full GC

猜你喜欢

转载自blog.csdn.net/snow_7/article/details/52274590