对象优先在Eden区分配
大对象直接进入老年代:-XX:PretenureSizeThreshold 参数,大于这个设置值的对象直接在老年代分配,这样做的目的是避免在 Eden 区及两个 Survivor 区之间发生大量的内存复制。
JVM 给每个对象定义了一个对象年龄计数器。当新生代发生一次 Minor GC 后,存活下来的对象年龄 +1,当年龄超过一定值时,就将超过该值的所有对象转移到老年代中去。使用-XXMaxTenuringThreshold 设置新生代的最大年龄,只要超过该参数的新生代对象都会被转移到老年代中去。动态对象年龄判定:如果当前新生代的 Survivor 中,相同年龄所有对象大小的总和大于 Survivor 空间的一半,年龄 >= 该年龄的对象就可以直接进入老年代,无须等到 MaxTenuringThreshold 中要求的年龄。
空间分配担保:通过清除老年代中废弃对象来扩大老年代空闲空间,以便给新生代作担保。
可能触发
JVM进行Full GC的情况:
System.gc()方法的调用- 老年代空间不足
引用计数法:在对象头维护着一个 counter 计数器,对象被引用一次则计数器 +1;若引用失效则计数器 -1。当计数器为 0 时,就认为该对象无效了。弊端:难解决对象之间循环引用的问题。
可达性分析法:所有和 GC Roots 根对象直接或间接关联的对象都是有效对象,和 GC Roots 没有关联的对象就是无效对象。
GC Roots 包括:
GC Roots 并不包括堆中对象所引用的对象,这样就不会有循环引用的问题。
分代收集理论
复制算法(新生代)
标记-清理
标记-整理
Serial 最早出现的垃圾收集器单线程,在进行垃圾收集时,会暂停其他工作线程(
stop the world)
ParNew,serial的多线程并行版,新生代收集器(与serial一样带有空间压缩整理的能力,采用指针碰撞的分配算法来给对象分配内存);
Serial old
parallel Scavenge
致力于达到一个可控制的吞吐量(吞吐量=用户线程执行时间/用户线程执行时间+垃圾收集线程执行时间)
parallel oldCMS:老年代的收集器,(基于清除算法,采用空闲列表来给对象分配内存);首次实现了让垃圾收集线程与用户线程(基本上)同时工作,致力于缩短回收停顿时间。
运作过程
G1面向全堆的收集器,不需要和其他收集器配合一起工作
使用region划分内存空间,并且维护优先级列表(跟踪各个region区域回收所获得的空间大小以及回收所需时间数据)
运作过程