垃圾收集的种类

主要分MinorGC和FullGC。

MinorGC也成为新生代GC,会释放新生代中不可达对象所占的内存。

FullGC通常会收集整个堆,包括新生代、年老代、永久代,除了将新生代中的活跃对象提升到年老代之外,还会压缩年老代和永久代,因而FullGC之后,新生代为空,年老代和永久代也压缩整理并且只有活跃对象。


垃圾收集器主要分为两种:

(1)吞吐量优先(Throughput收集器)

目标:减少垃圾收集的开销从而增加服务类应用的吞吐量

MinorGC和FullGC都是并行的,hotspot中是Parallel收集器

吞吐量优先的收集器提供了自适应堆调整,并默认开启(Adaptive Heap Sizing),hotspot会监控java应用中对象的分配速率和生命期,然后决定如何调整新生代空间,使得存活期短的对象在尚未提升到年老代之前就会被收集,同时允许存活时间长的对象适时地被提升,避免在Survivor区之间进行不必要的复制。

当然也可以显示指定新生代的设置,-Xmn,-XX:NewSize,-XX:MaxNewSize,-XX:NewRatio,-XX:SurvivorRatio,这些是新生代调整的起始点,自适应调整就是从这些初始设置开始自动调整新生代空间大小。

注意非吞吐量优先的收集器不提供自适应堆调整。



(2)低延迟优先

目标:减少垃圾收集的停顿时间

hotspot中为Concurrent Mark-Sweep GC,和G1收集器


在使用吞吐量优先的垃圾回收器时(-XX:+UseParallelOldGC或-XX:+UseParallelGC),如果关闭-XX:-ScavengeBeforeFullGC,则hotspot vm在FullGC之前不会进行MinorGC,如果开启的话,FullGC之前会先进行MinorGC,分担一部分原本FullGC要做的工作,使得在这两次独立的GC之间java线程有机会得以运行,从而缩短最大停顿时间,但也拉长了整体的停顿时间。


过早提升(Premature Promotion),MinorGC过程中,Survivor可能不足以容纳Eden和另外一个Survivor中存活的对象,如果Survivor中的存活对象溢出,多余的对象将被移到年老代。

在MinorGC过程中,如果年老代满了无法容纳更多的对象,则MinorGC之后,通常会进行FullGC,这将导致遍历整个java堆,这称为提升失败(Promotion Failure)


并发模式失败(Concurrent Mode Failure):

(1)如果对象提升到年老代的速度太快,而CMS收集器不能保持足够多的可用空间时,就会导致年老代的运行空间不足;

(2)当年老代的碎片化达到某种程度,使得没有足够空间容纳从新生代提升上来的对象时,也会发生并发模式失败。

当发生并发模式失败时,年老代将进行垃圾收集以释放可用空间,同时也会整理压缩以消除碎片,这个操作需要停止所有的java应用线程,并且需要执行相当长时间。


分代垃圾回收机制基于弱分代假设,即

(1)大多数分配对象的存活时间很短

(2)存活时间久的对象很少引用存活时间短的对象


-XX:+PrintGCDateStamps,它可以生成符合IOS8601标准的时间戳,形如YYYY-MM-DD-T-HH-MM-SS.mmm-TZ

可以和-XX:+PrintGCDetails配合使用

-Xloggc:<filename>,可以将垃圾收集的统计数据直接输出到文件,以便离线分析


在jstack日志中查找锁竞争的关键在于,从多个线程的栈追踪信息中查找相同的锁地址,然后找到等待该锁地址的线程。如果发现多个线程的栈追踪信息都试图锁住相同的锁地址,说明应用正面临锁竞争。抓取多份jstack日志,如果在同一个锁上一直出现类似的锁竞争,那么应用极有可能正面临高度锁竞争问题。注意,栈追踪信息提供了发生锁竞争的代码在源代码中位置。



你可能感兴趣的:(垃圾收集的种类)