您的位置:首页 > 编程语言 > Java开发

JVM垃圾收集器(1)--G1之前GC方法概览

2017-01-20 15:05 302 查看
本文从总体上介绍JVM的垃圾收集器,其中JVM指HotSpot VM。

术语

分代垃圾收集; JVM将堆分成两个物理区:新生代(Minor GC)、老年代(Major GC)。永久代虽然称为代,但是实际上不应该看作分代层次的一部分。VM只是用它来存储元数据,例如类的数据结构、保留字符串(Interned String)等。





垃圾收集器使用称为卡表(Card Table)的数据结构,使其不用扫描整个老年代就能识别新生代中的存活对象,从而缩短Minor GC的时间。



Minor GC,Eden中的存活对象被复制到未使用的Survivor。被占用Survivor里不够老的存活对象也被复制到未使用的Survivor。最后Survivor里足够老的存活对象被提升到老年代。假如Survivor不足以容纳Eden和另一个Survivor中的存活对象,称作Survivor存活对象溢出,多余的对象将被移到老年代,这成为过早提升。应该调优尽量避免。



快速内存分配。大部分新生对象都是在Eden上(想想为什么),因为Minor GC以复制方式回收新生代,其好处在于回收以后Eden总为空,在Eden中运用被称为指针碰撞的技术就可以有效分配空间。这种技术追踪最后一个分配的对象(称为top),当新的分配请求时,分配器只需要检查top和Eden末端之间的空间是否能够容纳。如果能够容纳,top跳到新近分配对象的末端。而且VM采用线程本地分配缓冲区(TLAB),为每个线程设置各自的缓冲区,避免锁的使用。

Stop-The-World: 指GC运行的时候,Java应用程序的线程停止运行。

parallelSerial: parallel一般翻译作“并行”,当Parallel用来描述GC的时候,比如ParallelOld GCParNew,指的是该GC是多线程的,有多个线程同时处理该GC任务。相反,Serial GC指该GC是单线程的,仅有一个线程用来执行GC任务。

Concurrent:一般翻译作并发,当Concurrent用来描述GC的时候,指该GC任务执行的时候,Java应用程序可以同时执行。

垃圾收集器分类



垃圾收集器主要分为三类:

Serial收集器



年轻代采用复制算法,即 Eden + From –> To + 老年代

老年代采用滑动压缩标记-清除算法(Sliding Compacting Mark-Sweep),也称为**标记-压缩(Mark-Compa

ct)**垃圾收集器。

Serial收集器适合大多数对停顿时间要求不高和在客户端运行的应用。

Stop-The-World

使用内存开销最小,因此一般用于客户端程序。

Parallel 收集器



HotSpot VM中能够并行的垃圾收集器包括Parallel Scavenge 收集器(年轻代)、ParNew收集器(年轻代)和Parallel Old收集器。

Throughput收集器通常特指Parallel Scavenge收集器

可以把ParNew收集器和Parallel Old收集器认为是Serial的并行版本。老年代采用标记-压缩,年轻代采用复制算法。

主要关注应用的吞吐量

Stop-The-World

CMS



Mostly-Concurrent收集器,也称为并发标记清除收集器(Concurrent Mark-Sweep GC、CMS收集器)

老年代垃圾收集器,年轻代可以是Serial 或者 ParNew

CMS GC 和Parallel GC年轻代GC方法是相似的,不同的是老年代的GC方法。如上图所示,CMS老年代GC 分为四个阶段,分别是Initial-markMarking/Pre-cleaning, Remark, Concurren Sweeping。 其中Initial-markRemark阶段是stop-the-world。

优点:老年代垃圾收集停顿时间变短。

缺点:由于老年代采用清除算法,导致老年代堆内存碎片化;新生代停顿略微拉长;吞吐量比Parallel GC低,堆的大小有所增长,并且由于并发,垃圾收集还会占用应用的CPU时间。

总结

上面垃圾收集器各有各的优缺点,需要根据应用场景进行选择。为了满足相应场景下的各种性能指标以及尽可能充分利用系统资源,需要进行细致的调优。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jvm 垃圾收集器 Java