JVM学习笔记——内存分配和回收策略

  • 通常情况下会优先在Eden区分配。新生代一般分为一个Eden加两个Survivor,默认比例8:1:1。我们先看看年轻代,这个区域又被分为了一个Eden和两个Survivor区,看一张图:
    在这里插入图片描述
    从图中可以清楚的看到他们的关系是8:1:1。那为什么Eden占用这么多呢?因为对象都会在Eden区创建。每次只使用Eden区和一个Survivor区,当这两个区满了之后就会将还存活的对象复制到另一个空白区(MINOR GC),大家是不是在想那空间怎么会够用呢?其实年轻代的对象有98%都是朝生夕死的,所以根本不用担心不够用,这也是为什么比例是8:1:1而不是1:1的原因。
  • 大对象直接进入老年代。因为新生代一般使用复制算法,如果对象太大,在新生代复制的代价非常高,而且占内存。常见的大对象有:很大的字符串、很大的byte数组(比如图片等转成的字节数组)。
  • 长期存活的对象进入老年代。对象头有一个字段存放了对象的“年龄”信息,对象在新生代每经过一次Minor GC,就会+1,当它的年龄达到一定值(默认是15),就会进入老年代。
    -XX:MaxTenuringThreshold=15来设置多少岁后进入年老区
  • 动态对象年龄判定:对象年龄不一定要达到阈值才进入老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该值的对象,就可以直接进入老年代。
  • 空间分配担保:在发生Minor GC之前,JVM会检查老年代最大可用连续空间时候大于历次晋升到老年代对象的平均大小,如果大于,就允许分配担保,如果小于,就要进行一次Full GC。而如果允许了分配担保,结果发现装不下,就说明担保失败,那也会发起一次Full GC。
关于Full GC和Minor GC
  • 新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较块。
  • 老年代GC(Full GC/Major GC):值发生在老年代的垃圾收集动作,出现了Major GC,经常会伴有至少一次的Minor GC(但非绝对)。Major GC速度上一般比Minor GC慢十倍以上。
发布了142 篇原创文章 · 获赞 89 · 访问量 27万+

猜你喜欢

转载自blog.csdn.net/wangchengming1/article/details/103478773
今日推荐