三、内存分配与回收策略

此笔记出自《深入理解java虚拟机 第二版》,仅做摘要整理,详细了解可购买相关书籍。


Java中的自动内存管理归根结底是为了自动化解决两个问题:

1、给对象分配内存

2、回收分配给对象的内存

回收分配给对象的内存是上面说到的,接下来说说第一个问题:给对象分配内存

对象的内存分配,宏观来说就是在队上分配,因为堆是存放对象实例的内存区域。(也有可能经过JIT编译后拆散为标量间接的分配到栈上)对象主要分配在新生代的Eden区上,少数情况下可能直接分配到老年代上。接下来讲讲规矩

  • 对象优先分配在Eden区上
    • 大多数情况,对象在新生代Eden区中分配,当Eden区没有足够空间时,虚拟机将发起一次Minor GC

Minor GC、Full GC、Major GC

新生代GC(Minor GC) : 因为新生代生老病死的速度很快,所以Minor GC非常频繁,回收速度也很快

老年代GC(Major GC / Full GC):Major GC通常会伴随至少一次Minor GC,Major GC速度比Minor GC慢10倍以上。


  • 大对象直接进入老年代

    • 大对象:大量连续内存空间的Java对象,比如长字符串或大数组。因为大对象容易导致内存还有很多空间时就触发垃圾收集。
  • 长期存活对象进入老年代

    • 对象出生后,在Eden区闯荡,每次Minor GC后,它的年龄就+1,默认15岁后,新生代变成老年代。
  • 动态对象年龄判定

    • 并非一定要达到指定年龄才能变成老年代,如果在Survivor空间里,相同年龄所有对象大小的总和大于Survivor空间的一半,年能大于等于该年龄的对象就可以直接进入老年代,无需到达指定年龄。
  • 空间分配担保

    • Minor GC时,Survivor空间不够用,老年代空间出来进行担保

三、内存分配与回收策略