达升笑讲故事 2019-06-17 09:00:06
内存分配策略
1、对象优先分配在新生代Eden区
多数情况下,对象分配在新生代的Eden,若Eden区域内存不够,则引发一次Minor GC
2、大对象直接进入老年代
大对象直接分配在老年代,避免新生代里出现从Eden到Survivor频繁的内存复制
可用 -XX:PretenureSizeThreshold设置,大于此值的对象直接分配在老年代
典型的大对象有长字符串或者数组等。
3、长久存活的对象进入老年代
有的对象经过几次MinorGC都没有被回收,则可以被移入老年代
可用-XX:MaxTenuringThreshold 用来定义年龄的阈值(-XX:MaxTenuringThreshold=3,设置垃圾最大年龄为3,即对象在Survivor区存在的年龄为3(复制一次年龄+1)。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。)
4、动态对象年龄判断
有时也不需要存活对象的年龄达到设置的年龄阀值,如果在 Survivor 中相同年龄所有对象大小的总和大于 Survivor 空间的一半,则年龄大于或等于该年龄的对象可以直接进入老年代
5、空间分配担保
在MinorGC之前,检查一下老年代连续可用内存空间是否大于新生代中所有对象大小和,若大于,则可以进行一次MinorGC;
若小于,则检查HandlePromotionFailure,若允许担保,则查看老年代连续可用内存大小是否大于上一次MinorGC进入老年代的平均大小,如果大于,则尝试一次MinorGC,若小于或者系统不允许冒险,则进行一次FullGC
内存回收策略
Minor[ˈmaɪnər] GC
1、回收范围与特点:回收新生代区域的对象,因为新生代对象存活时间短,所以MinorGC会频繁进行,花费的时间短
2、触发条件:当Eden区域内存满了的时候
Full GC
1、回收范围与特点:回收老年代和新生代两块区域,老年代对象存活时间长,所以FullGC进行的不频繁,但是执行速度比MinorGC慢很多
2、触发条件:
- System.gc()
- 只是建议虚拟机进行一次FullGC,并不能控制虚拟机一定执行,不建议这种方式,而是让虚拟机管理内存
- 老年代空间不够
- 空间分配担保失败
- jdk1.7及以前的永久代空间不够
- Concurrent Mode Failure