DepthJVM-垃圾收集器与内存分配策略

1、对象是否“存活”
引用计数器:每个对持有一个计数器,被引用时加1,引用失效时减1,难以解决循环引用问题
可达性分析:当对象到GC Roots没有引用链时表示该对象不可用
GC Roots:枚举根节点,必须Stop The World;可以作为根节点的节点:1.虚拟机栈(本地变量表)中引用的对象 2本地方法栈中JNI引用的对象 3.方法区中类静态属性引用的对象 4.方法区中常量引用的对象
2、引用
强引用:只要存在,GC不回收
软引用:空间不足时回收
弱引用:立即回收
虚引用:唯一目的就是在这个对象被回收时能够收到一个系统通知
3、对象回收标记
对象真正回收,至少需要两次标记:可达性分析之后标记,进行筛选,条件是此对象是否又必须要执行finalize()方法,如果对象没有覆盖finalize()或者已经被执行过则认为没必要执行,直接回收;如果有必要则将对象放置到F-Queue队列,并在稍后由一个JVM自动建立、低优先级的Finalizer线程执行(触发finalize()但不承诺等待执行结束,防止一个线程引起整个队列永久等待)。finalize()是对象逃脱回收的最有一次机会,稍后GC会对F-Queue进行第二次小规模标记,如果对象在finalize()与引用链上的任何一个对象建立关联,第二次标记时就会被移除出“即将回收”集合,如果没有就真的被回收
注:finalize()只执行一次,因此不可能出现两次逃脱回收
4、回收方法区
废弃常量:没有被引用的常量
无用类:回收条件1.所有实例都已被回收,Java堆中不存该类实例 2.该类的ClassLoader被回收 3.该类对应的Class对象没有任何地方引用,无法在任何地方通过反射访问该类的方法
5、垃圾收集算法
标记-清除算法:
复制算法:
标记-整理算法:
分代收集算法:新生代每次GC都有大量对象被回收,使用"复制"算法;老年代对象存活率高、没有额外空间对它进行分配担保,只用"标记-清除"或"标记-整理"算法
6、枚举根节点
当Stop The World发生之后,JVM能够通过OopMap找到哪些地方存放着对象引用,类加载完成后会在"特定的位置"(安全点)形成OopMap记录,记录下栈和寄存器哪些位置是引用
7、安全点(SafePoint)
记录OopMap的位置称为安全点,程序只有到达安全点才能暂停
安全点选取:太少导致GC等待时间长,太多导致系统运行负荷增大;安全点选定以程序"是否具有让程序长时间执行的特征"为标准,"长时间执行"最明显的特征就是指令序列复用,如方法调用、循环跳转、异常跳转等,具有这些功能的指令会产生SafePoint
安全点到达:1.主动式中断:GC时设置标志,各个线程执行时轮询该标志,为真则自己中断挂起;轮询标志的地方和安全点重合,另外再加上创建对象需要分配内存的地方 2.抢先式中断:GC时中断所有线程,没有到达安全点的恢复,直到跑到安全点
8、安全区域(Safe Region)
安全点解决了线程执行时对GC中断响应的问题,如果线程未执行(如sleep/blocked)则需要安全区域来解决。安全区域是指在一段代码中,引用关系不会发生变化,在这个区域的任意地方GC都是安全的。在线程执行到Safe Region时首先标识自己进入,离开时要检查系统是否已经完成了根节点枚举,如果未完成则要等待收到可以离开Safe Region的信息为止。GC发生时不用管Safe Region中的线程。
9、垃圾收集器
年轻代:复制算法
Serial:单线程、Stop The World、Client模式默认、简单高效
ParNew:Serial的多线程版本、Server模式默认、-XX:+UseConcMarkSwapGC模式、默认线程数与CPU数相同、-XX:+UseParNewGC、-XX:ParallelGCThreads
Parallel Seavenge:关注吞吐量(运行代码时间/运行代码时间+GC时间)、-XX:MaxGCPauseMillis(GC停顿时间,缩短GC停顿时间是以牺牲吞吐量和新生代空间换取的)、-XX:GCTimeRatio(运行代码时间/GC时间)、-XX:UseAdaptiveSizePolicy(GC自适应策略)
老年代:
Serial Old:标记-整理、Serial老年代版本
Parallel Old:标记-整理、ParNew老年代版本
CMS:标记-清除、初始标记(STW)-并发标记-重新标记(STW)-并发清除、缺点(1.CPU敏感,默认线程数=(CPU+3)/4,CPU不足4个时CMS对用户程序影响较大 2.无法清理浮动垃圾-并发清理阶段由于程序运行产生的垃圾,可能出现"Concurrent Mode Failure"而导致另一次FullGC,GC阶段用户线程还在运行,因此需要预留足够内存给用户线程使用,因此CMS无法像其他收集器一样等到老年代几乎被填满时再进行收集,-XX:CMSInitiatingOccupancyFraction设置老年代触发CMS时使用比率,JDK1.6之后默认92%,该值过高容易导致大量"Concurrent Mode Failure" 3.内存碎片,-XX:+UseCMSCompactAtFullCollection默认开启,在CMS顶不住要进行FullGC时进行内存碎片整理,导致停顿时间延长,-XX:CMSFullGCsBeforeCompaction设置执行多少次不压缩的FullGC之后进行一次压缩的,默认0表示每次FullGC都进行碎片整理)
10、垃圾收集器参数总结
UseSerialGC:Serial + Serial Old
UseParNewGC:ParNew + Serial Old
UerParallelGC:Parallel Scavenge + Parallel Old
UseParallelOldGC:Parallel Scavenge + Parallel Old
UseConcMarkSweeGC:ParNew + CMS + Serial Old
SurvivorRatio:
PretenureSizeThreshold
MaxTenuringThreshold
HandlePromotionFailure:担保失败
ParallelGCThreads
MaxGCPauseMillils
GCTimeRatio
UseAdapativeSizePolicy
CMSInitiatingOccupancyFraction
UseCMSCompactAtFullCollection
CMSFullGCsBeforeCompaction
11、动态对象年龄判定
Survivor空间中相同年龄对象大小总和大于Survivor空间的一半,则大于等于改年龄的对象直接进入老年代
12、空间分配担保
Minor GC之前,JVM检查老年代最大可用连续空间大小是否超过年轻代对象总大小,如果大于则Minor GC安全;小于则检查是否允许担保失败(HandlePromotionFilure),如果允许则检查老年代最大可用连续空间大小是否超过历次晋升入老年代对象总大小的平均值,如果大于则冒险进行Minor GC,失败进行Full GC;如果小于或不允许担保失败则直接Full GC
JDK 6 Update24之后,只要老年代最大可用连续空间大于年轻代对象总大小或者历次晋升入老年代对象总大小的平均值,直接进行Minor GC;否则进行Full GC








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值