首页 / 软件开发 / JAVA / JVM内存管理:垃圾搜集器详解
JVM内存管理:垃圾搜集器详解2014-10-14引言在上一章我们已经探讨过hotspot上垃圾搜集器的实现,一共有六种实现六种组合。本次LZ与各位一起探讨下这六种搜集器各自的威力以及组合的威力如何。为了方便各位的观看与对比,LZ决定采用当初写设计模式时使用的方式,针对某些搜集器,分几个维度去解释这些搜集器。client模式与server模式在介绍本章内容之前,要说一下JVM的两种模式,一种是client模式,一种是server模式。我们平时开发使用的模式默认是client模式,也可以使用命令行参数-server强制开启server模式,两者最大的区别在于在server模式下JVM做了很多优化。server模式下的JAVA应用程序启动较慢,不过由于server模式下JVM所做的优化,在程序长时间运行下,运行速度将会越来越快。相反,client模式下的JAVA应用程序虽然启动快,但不适合长时间运行,若是运行时间较长的话,则会在性能上明显低于server模式。搜集器详解以下我们先探讨一下单个垃圾搜集器的相关内容,最后我们再简单的谈一下组合之后,各个组合的特点。Serial Garbage Collector算法:采用复制算法内存区域:针对新生代设计执行方式:单线程、串行执行过程:当新生代内存不够用时,先暂停全部用户程序,然后开启一条GC线程使用复制算法对垃圾进行回收,这一过程中可能会有一些对象提升到年老代特点:由于单线程运行,且整个GC阶段都要暂停用户程序,因此会造成应用程序停顿时间较长,但对于小规模的程序来说,却非常适合。适用场景:平时的开发与调试程序使用,以及桌面应用交互程序。开启参数:-XX:+UseSerialGC(client模式默认值)Serial Old Garbage Collector这里针对serial old搜集器不再列举各个维度的特点,因为它与serial搜集器是一样的,区别是它是针对年老代而设计的,因此采用标记/整理算法。对于其余的维度特点,serial old与serial搜集器一模一样。ParNew Garbage Collector算法:采用复制算法内存区域:针对新生代设计执行方式:多线程、并行执行过程:当新生代内存不够用时,先暂停全部用户程序,然后开启若干条GC线程使用复制算法并行进行垃圾回收,这一过程中可能会有一些对象提升到年老代特点:采用多线程并行运行,因此会对系统的内核处理器数目比较敏感,至少需要多于一个的处理器,有几个处理器就会开几个线程(不过线程数是可以使用参数-XX:ParallelGCThreads=<N>控制的),因此只适合于多核多处理器的系统。尽管整个GC阶段还是要暂停用户程序,但多线程并行处理并不会造成太长的停顿时间。因此就吞吐量来说,ParNew要大于serial,在处理器越多的时候,效果越明显。但是这并非绝对,对于单个处理器来说,由于并行执行的开销(比如同步),ParNew的性能将会低于serial搜集器。不仅是单个处理器的时候,如果在容量较小的堆上,甚至在两个处理器的情况下,ParNew的性能都并非一定可以高过serial。适用场景:在中到大型的堆上,且系统处理器至少多于一个的情况开启参数:-XX:+UseParNewGCParallel Scavenge Garbage Collector这个搜集器与ParNew几乎一模一样,都是针对新生代设计,采用复制算法的并行搜集器。它与ParNew最大的不同就是可设置的参数不一样,它可以让我们更精确的控制GC停顿时间以及吞吐量。URL:http://www.bianceng.cn/Programming/Java/201410/45825.htmparallel scavenge搜集器提供参数主要包括控制最大的停顿时间(使用-XX:MaxGCPauseMillis=<N>),以及控制吞吐量(使用-XX:GCTimeRatio=<N>)。由此可以看出,parallel scavenge就是为了提供吞吐量控制的搜集器。不过千万不要以为把最大停顿时间调的越小越好,或者吞吐量越大越好,在使用parallel scavenge搜集器时,主要有三个性能指标,最大停顿时间、吞吐量以及新生代区域的最小值。parallel scavenge搜集器具有相应的调节策略,它将会优先满足最大停顿时间的目标,次之是吞吐量,最后才是新生代区域的最小值。因此,如果将最大停顿时间调的过小,将会牺牲整体的吞吐量以及新生代大小来满足你的私欲。手心手背都是肉,我们最好还是不要这么干。不过parallel scavenge有一个参数可以让parallel scavenge搜集器全权接手内存区域大小的调节,这其中还包括了晋升为年老代(可使用-XX:MaxTenuringThreshold=n调节)的年龄,也就是使用-XX:UseAdaptiveSizePolicy打开内存区域大小自适应策略。parallel scavenge搜集器可使用参数-XX:+UseParallelGC开启,同时它也是server模式下默认的新生代搜集器。Parallel Old Garbage CollectorParallel Old与ParNew或者Parallel Scavenge的关系就好似serial与serial old一样,相互之间的区别并不大,只不过parallel old是针对年老代设计的并行搜集器而已,因此它采用标记/整理算法。Parallel Old搜集器还有一个重要的意义就是,它是除了serial old以外唯一一个可以与parallel scavenge搭配工作的年老代搜集器,因此为了避免serial old影响parallel scavenge可控制吞吐量的名声,parallel old就作为了parallel scavenge真正意义上的搭档。它可以使用参数-XX:-UseParallelOldGC开启,不过在JDK6以后,它也是在开启parallel scavenge之后默认的年老代搜集器。Concurrent Mark Sweep Garbage Collectorconcurrent mark sweep(以下简称CMS)搜集器是唯一一个真正意义上实现了应用程序与GC线程一起工作(一起是针对客户而言,而并不一定是真正的一起,有可能是快速交替)的搜集器。CMS是针对年老代设计的搜集器,并采用标记/清除算法,它也是唯一一个在年老代采用标记/清除算法的搜集器。