垃圾回收机制

判断内存回收的方式

1.引用计数:引用为0则回收
2.可达性分析:将对象及其引用关系看做一个图,选定活动对象作为GC ROOT ,然后跟踪引用链条,如果一个对象和GC ROOT之间不可达,则不存在引用,那么认为是可回收对象。
3.方法区回收:
本章主要介绍可达性分析

引用类型和可达性级别

引用类型

1.强引用StrongReference:最为常见的普通对象引用,只要还有强引用指向的对象就不能回收。(如new Object)
2.软引用SoftReference:JVM认为内存不足时才会去尝试回收引用指向对象(如缓存)
3.弱引用WeakReference:虽然是引用,但是随时可能被回收
4.虚引用PhantomReference:不能通过它访问对象。它是当对象被使用之后,GC时进行的逻辑操作,如堆外内存回收时会触发Cleaner操作

可达性级别

1.强可达Strongly Reachable:一个对象可以有一个或多个线程可以通过不同引用访问到的情况。
2.软可达Softly Reachable:我们只能通过软引用才能访问到对象的状态。
3.弱可达Weakly Reachable:只能通过弱引用访问时的状态。当弱引用被清除的时候,就符合销毁条件。
4.幻象可达Phantom Reachable:不存在其他引用,并且finalize过了,只有幻象引用指向这个对象。
5.不可达unreachable:这个对象可以被清除。

垃圾回收算法

1.标记-清除算法 Mark-Sweep:首先标记出所有要回收的对象,然后清除。效率有限,而且会出现内存碎片化,不适合特别大的堆;其他收集算法都基于标记-清除思路进行改进。
2.复制算法 Copying:划分两块同等大小的区域,收集时将活着的对象复制到另一块区域。拷贝过程中将对象顺序放置,避免内存碎片化,复制+预留内存,需要双倍内存。
3.标记-整理Mark-Compact:类似于标记-清除,但是为了避免内存碎片化,它会在清理过程中将对象移动,以确保移动后的对象占用连续的内存空间。

分代收集

根据对象的存活周期,将内存分为几个区域,不同区域采用适合的垃圾收集算法。新对象分配到Eden,如果超过-XX:PretenureSizeThreshold:设置大对象直接进入老年代阈值。
新生代回收:在Eden区之后还有存活区Survivor,分为S0、S1,当Eden区GC时会把存活对象复制到S0,并将对象的回收次数+1,当新生代回收时同样会把S0的存活对象复制S1,并将对象回收次数+1,如此反复,当对象回收次数达到一定阈值时,则将这个对象移动至老年代,而如果有一个大对象创建时,会根据-XX:PretenureSizeThreshold参数设置来判断是否达到直接放入老年代的阈值。新生代的回收机制是复制算法。
老年代回收:当老年代回收时,会做标记删除,然后整理对象,达到连续内存空间的效果,老年代使用的是标记-整理算法。

垃圾收集器

串行收集器

串行收集器:-Serial GC -XX:+UseSerialGC
单线程执行所有垃圾收集工作,适合单核处理器
在Client模式下JVM默认选项
串行收集器:-Serial Old -XX:+UseSerialOldGC
可以在老年代使用,它采用标记-整理算法,区别于新生代的复制算法

并行收集器

并行收集器:-Parallel GC -XX:+UseParallelGC
-Parallel Old GC -XX:+UseParallelOldGC
server模式JVM的默认GC选择,整体算法和Serial比较相似,区别是新生代和老年代GC都是并行进行;可以设置GC时间或吞吐量等值,可以自动进行适应性调整Eden,Survivor大小和MaxTenuringThreshold的值。
也称为吞吐量优先的GC:吞吐量=用户代码运行时间/(用户代码运行时间+GC时间)
-XX:ParallelGCThreads:设置用于垃圾回收的线程数。通常=CPU核数
-XX:MaxGCPauseMills:设置最大垃圾收集停顿时间。它的值是一个大于0的整数
-XX:GCTimeRatio:设置吞吐量大小,它的值是一个0-100之间的整数
-XX:+UseAdaptiveSizePolicy:打开自适应FC策略。以达到在堆大小、吞吐量和停顿时间之间的平衡点。

并发收集器

-CMS(Concurrent Mark Sweep)GC -XX:+UseConcMarkSweepGC
专用老年代,基于标记-清除算法,设计目标是减少STW的时间。采用标记-清除算法存在着内存碎片化问题,长时间运行等情况下发生fullGC,导致恶劣的STW。CMS会占用更多CPU资源,并和用户线程争抢。
回收步骤:

  1. 初始标记(CMS-initial-mark) ,会导致swt;
  2. 并发标记(CMS-concurrent-mark),与用户线程同时运行;
  3. 预清理(CMS-concurrent-preclean),与用户线程同时运行;
  4. 可被终止的预清理(CMS-concurrent-abortable-preclean) 与用户线程同时运行;
  5. 重新标记(CMS-remark) ,会导致swt;
  6. 并发清除(CMS-concurrent-sweep),与用户线程同时运行;
  7. 并发重置状态等待下次CMS的触发(CMS-concurrent-reset),与用户线程同时运行;
    CMS在gc时(CMS的GC不是fullgc,它只作用于老年代)会占用大量内存和cpu资源,用资源来换取STW时间的减少,当用户占用资源达到一定阈值时,CMS没有足够的空间来做对象标记。此时的回收就会变得缓慢,STW时间会变长,并且由于用户线程处于等待,也无法释放资源提升CMS标记效率,从而进一步增加了stw时间,而由于在STW时间内没有进行GC释放资源,有可能因为内存的大量占用的导致系统触发fullgc,那么此时可能出现的问题就是内存溢出。
    CMS是真正意义上实现用户操作线程与GC线程并发执行的收集器。减少了停顿时间,这一点对于互联网web等对于时间敏感的系统非常重要,直到目前,仍有很多系统使用CMSGC。
缺点:

1.CMS的标记清除算法会产生内存碎片,而大量内存碎片会导致当内存足够的时候,有大对象进入老年代时会因为没有整块空间而无法存入老年代,此时就会被动触发fullgc
2.CMS收集器对CPU资源非常敏感。在并发阶段,它虽然不会导致用户线程停顿,但是会因为占用了一部分线程而导致应用程序变慢,总吞吐量会降低。
3.由于CMS并发清理阶段用户线程还在运行着,伴随着程序运行自然就会有新的垃圾不断产生,这部分垃圾出现的标记过程之后,CMS无法在当次收集中处理掉它们,只好留待下一次GC中再清理。这些垃圾就是“浮动垃圾”

-G1 -XX:+UseG1GC
针对大堆内存设计的收集器,兼顾吞吐量和停顿时间,JDK9之后的默认收集器,目标是替代CMS;G1将堆分成固定大小的若干区域,Region之间是复制算法,但是整体上可以看做是标记整理算法,可以有效的避免内存碎片,在找不到大内存时会执行FullGC

并行收集器

-ParNew GC -XX:+UseParNewGC
新生代GC实现,它实际是SerialGC的多线程版本。
在并行收集的过程中,用户线程还是处于等待状态的。
可以控制线程数量,参数:-XX:ParallelGCThreads
最常见的应用场景是配合老年代CMSGC工作。参数-XX:+UseConcMarkSweepGC
采用复制算法 将s0标记

收集器的使用

使用的是ParNew+CMS,原因是CMS是jdk1.5时候出现的并发收集器,只能与ParNew配合使用,与其他收集器不兼容。

G1收集器

G1是一款面向服务端应用的垃圾收集器。G1具备如下特点:

1、并行于并发:G1能充分利用CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短stop-The-World停顿时间。部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让java程序继续执行。

2、分代收集:虽然G1可以不需要其他收集器配合就能独立管理整个GC堆,但是还是保留了分代的概念。它能够采用不同的方式去处理新创建的对象和已经存活了一段时间,熬过多次GC的旧对象以获取更好的收集效果。

3、空间整合:与CMS的“标记–清理”算法不同,G1从整体来看是基于“标记整理”算法实现的收集器;从局部上来看是基于“复制”算法实现的。

4、可预测的停顿:这是G1相对于CMS的另一个大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,

5、G1运作步骤:

1、初始标记;2、并发标记;3、最终标记;4、筛选回收

上面几个步骤的运作过程和CMS有很多相似之处。初始标记阶段仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS的值,让下一个阶段用户程序并发运行时,能在正确可用的Region中创建新对象,这一阶段需要停顿线程,但是耗时很短,并发标记阶段是从GC Root开始对堆中对象进行可达性分析,找出存活的对象,这阶段时耗时较长,但可与用户程序并发执行。而最终标记阶段则是为了修正在并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录,虚拟机将这段时间对象变化记录在线程Remenbered Set Logs里面,最终标记阶段需要把Remembered Set Logs的数据合并到Remembered Set Logs里面,最终标记阶段需要把Remembered Set Logs的数据合并到Remembered Set中,这一阶段需要停顿线程,但是可并行执行。最后在筛选回收阶段首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值