三、内存分配与回收策略
此笔记出自《深入理解java虚拟机 第二版》,仅做摘要整理,详细了解可购买相关书籍。
Java中的自动内存管理归根结底是为了自动化解决两个问题:
1、给对象分配内存
回收分配给对象的内存是上面说到的,接下来说说第一个问题:给对象分配内存
对象的内存分配,宏观来说就是在队上分配,因为堆是存放对象实例的内存区域。(也有可能经过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空间不够用,老年代空间出来进行担保