-
引用计数法
问题:引用的加减法,影响性能,很难处理循环引用
-
标记-清除法是现代垃圾回收算法的思想基础,先标记可达,清楚不可达
-
标记-压缩,适合存活对象较多的场合,如老年代。标记后,将存活对象压缩到一端,清理边界外所有的空间。
-
复制算法,(空间浪费,整合标记清理思想)不适合存活对象校多的场合,如老年代
依据对象的存活周期进行分类,短命对象归为新生代,长命对象归为老年代
-
根据不同代的特点,选取合适的收集算法
少量对象存活,适合复制算法
大量对象存活,适合标记清理或者是标记压缩算法
finalize()方法只能被调用一次,之后调用无效。
- 避免使用finalize(),操作不慎可能导致错误
- finalize(),优先级低,何时调用不确定,在发生gc之前
- 可以使用try-catch-finally来替代
根
- 栈中引用的对象
- 方法区中静态成员或常量应用的对象(全局对象)
- JNI方法中引用的对象
Stop-The-World
- java中全局暂停的现场
- 全局停顿,所有Java代码停止,native代码可以执行,但不能和jvm交互
- 多半由GC引起,(Dump线程,死锁检查,堆Dump等都可以引起)
串行收集器
-
最古老,最稳定,效率高
-
可能会产生较长时间的停顿(只能一个线程回收)
-
启动方式:-XX:+UseSerialGC
效果:
- 新生代,老年代使用串行回收
- 新生代复制算法
- 老年代标记-压缩
并行收集器
-
ParNew
- -XX:+UseParNewGC
- 新生代并行
- 老年代串行
- Serial收集器新生代的并行版本
- 复制算法
- 多线程,需要多核支持
- -XX:ParallelGCThreads 限制线程数量
- -XX:+UseParNewGC
-
Parallel收集器
- 类似ParNew
- 新生代复制算法
- 老年代标记-压缩算法
- 更加关注吞吐量
- -XX:+UseParallelGC
- 使用Parallel收集器+老年代串行
- -XX:+UseParallelOldGC
- 使用Parallel收集器+(新生代,老年代)并行
并行收集器GC参数
- -XX:MaxGCPauseMills 最大停顿时间,单位毫秒,GC尽量保证不超过这个设定值,
- -XX:GCTimeRatio 垃圾收集时间占总时间的百分比,0-100的取值范围,默认99,即最大允许1%时间做GC,应用程序的时间占用越多,吞吐量越大,GC的时间越少
- 这两个参数是矛盾的,因为停顿时间和吞吐量不可能同时调优
CMS收集器*(老年代收集器)
- Concurrent Mark Sweep 并发标记清除
- 理论上gc线程可以和应用程序的线程一起执行,停顿时间较少
- 标记-清除算法
- 与标记-压缩相比
- 并发阶段会降低吞吐量
- 老年代收集器(新生代使用ParNew)
- -XX:+UseConcMarkSweepGC (打开标记)
CMS运行过程比较复杂(试图和应用线程一起执行),着重实现了标记的过程,可分为
- 初始标记(会产生全局停顿)
- 根可以直接关联的对象
- 速度快
- 并发标记(和用户线程一起)
- 主要标记过程,标记全部对象
- 重新标记(独占CPU,会产出停顿)
- 由于并发标记时,用户线程依然运行,因此在正式清理前,再做修正
- 并发清除(和用户线程一起)
- 基于标记结果,直接清理对象
主要的步骤可以和用户线程一起执行,关键的步骤还是会产生全局停顿,因此可以说是把全局停顿尽可能的缩小,但是不能完全的消除停顿。
只能并发标记不能并发清理或是并发压缩,是因为把对象移动位置的,应用程序很难正常执行,所以只是简单清除,没有压缩
CMS特点
- 尽可能降低停顿
- 会影响系统整体吞吐量和性能
- 比如,在用户线程运行过程中,分一半CPU去做GC,系统性能在GC阶段,反应速度就下降一半
- GC清理不彻底
- 因为在清理阶段,用户线程还在运行,会产生新的垃圾,无法清理
- 因为和用户线程一起执行,所以不能在空间快满时再清理
- -XX:CMSInitiatingOccupancyFraction 设置触发GC的阈值(当堆空间占用达到百分之多少的时候,就会触发GC)
- 如果不幸内存预留空间不够,就会引起concurrent mode failure(并发收集器收集失败)
标记清除和标记压缩的区别
清除会产生碎片,导致可用空间不连续,无法分配连续空间
-XX:+UseCMSCompactAtFullCollection Full GC后,进行一次整理
整理过程时独占的,会引起停顿时间变长
-XX:+CMSFullGCsBeforeCompaction
设置进行几次Full GC 后,进行一次碎片整理
-XX:ParallelCMSThreads
设定CMS的线程数量
移动可用空间的位置