深入JVM之——GC种类和实践

本文介绍了三种GC收集器:serialcollector、parallelcollector和concurrentcollector的工作原理及特点,并通过实验对比了它们在不同参数配置下的性能表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                

          首先,合理的配置GC收集器是开发一个高性能服务器的重要参数。现在让我们先来认识几个重要的GC收集器,然后带着大家来实践一下。

         一、 GC收集器按工作特性分类大致可分为3类:

          (1)serial collector :单线程收集器,使用单线程去完成所有的gc工作,没有线程间的通信,这种方式会相对高效,单处理器机器且没有pause time的要求。Client模式下默认可使用 。可用-XX:+UseSerialGC强制使用。优点:对server应用没什么优点。缺点:慢,不能充分发挥硬件资源

           (2)parallel collector:并行收集器。使用多线程的方式,利用多CUP来提高GC的效率。主要以到达一定的吞吐量为目标。适用于科学技术和后台处理有中规模/大规模数据集大小的应用且运行在多处理器上,关注吞吐量(throughput)。可用-XX:+UseParallelGC或-XX:+UseParallelOldGC强制指定。--ParallelGC代表FGC为Parallel MSC --ParallelOldGC代表FGC为Parallel Compacting 优点:高效 缺点:当heap变大后,造成的暂停时间会变得比较长

      (3)concurrent collector:并发收集器。使用多线程的方式,利用多CUP来提高GC的效率。并发完成大部分工作,使得gc pause短。适合中规模/大规模数据集大小的应用,应用服务器,电信领域关注response time,而不是throughpu。可用-XX:+UseConcMarkSweepGC强制指定 优点:对old进行回收时,对应用造成的暂停时间非常端,适合对latency要求比较高的应用缺点:1.内存碎片和浮动垃圾2.old去的内存分配效率低3.回收的整个耗时比较长4.和应用争抢CPU

       注:想必单线程大家都能理解,我来解释一下。并行收集器和并发收集器的区别,并行表示开启多个GC线程去回收垃圾对象,但是回收过程中应用程序依然会停顿。总得来讲它只是单线程收集器改良的多线程版。而并发收集器允许GC线程和应用程序线程同时执行,所以并发收集器相对前两种收集器来说算法比较复杂。

            二、三种收集器的实验分别如下

              serial collector :

                             -XX:+UseSerialGC  新老代全是用串行回收

              parallel collector:

                -XX:+UseParNewGC 多线程收集。可与CMS收集同时使用。在serial基础上实现的多线程收集器。在收集器只对年轻代有效。但此时用户线程必须停止

                                     -XX:+UseParallelGC:垃圾收集器为并行收集器。此配置仅对年轻代有效。可以同时并行多个垃圾收集线程,但此时用户线程必须停止。 -XX:+UseParallelGC-XX:+UseParNewGC最大的不同是后者可与CMS配合使用。

                                                  -XX:+UseParallelOldGC:这个是老年代使用并行收集器。

            concurrent collector

              -XX:+UseConcMarkSweepGC:并发收集器的实现,针对老年代。算法复杂。工作中会分一半CPU去工作,虽然不会停顿应用线程,但是会

    三、实验测试。

                  目的:测试网页吞吐量

              环境:tomcat7 JSP网站

              工具:JMeter

              方式:建立10个线程,每个线程请求Tomcat 1000次 共10000次请求

           (1)JDK6:使用32M堆处理请求
参数:set CATALINA_OPTS=-server -Xloggc:gc.log -XX:+PrintGCDetails -Xmx32M -Xms32M -XX:+HeapDumpOnOutOfMemoryError -XX:+UseSerialGC -XX:PermSize=32M

结论:因为堆只有32M,所以FullGC频繁执行

          (2)set CATALINA_OPTS=-Xmx512m -XX:MaxPermSize=32M  -Xloggc:gc.log -XX:+PrintGCDetails


结论:增大堆空间后明显改善Full GC的执行次数。但新生代 的GC依然很多。新生代空间也从初始的15872k增大到60456k说明GC要维持最小堆空间所以才不断的执行以逐渐增加堆空间来供给程序的开销。


       (3)set CATALINA_OPTS=-Xmx512m -Xms64m -XX:MaxPermSize=32M  -Xloggc:gc.log -XX:+PrintGCDetails



结论: GC数量减少 且性能有略微提升

        (4)set CATALINA_OPTS=-Xmx512m -Xms64m -XX:MaxPermSize=32M  -Xloggc:gc.log -XX:+PrintGCDetails -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:ParallelGCThreads=4



结论:GC压力原本就不大,改用并行回收器之后反而略微影响了性能。


          (5)减小堆大小,增加GC压力,使用Serial回收器set CATALINA_OPTS=-Xmx40m -Xms40m -XX:MaxPermSize=32M  -Xloggc:gc.log -XX:+PrintGCDetails

结论:当我们减小堆大小后,使用默认回收器.间接增大了GC压力,我们发现性能下降还是比较明显的。


        (6)减小堆大小,增加GC压力,使用ParNew回收器set CATALINA_OPTS=-Xmx40m -Xms40m -XX:MaxPermSize=32M  -Xloggc:gc.log -XX:+PrintGCDetails -XX:+UseParNewGC

结论:当我们在年轻代改用 -XX:+UseParNewGC后我们发现,性能提升。MAX明显变小

          (7)JDK测试

 启动Tomcat 7 使用JDK6 不加任何参数启动测试

  启动Tomcat 7  使用JDK7  不加任何参数启动测试

结论:升级JDK可能会带来额外的性能提升!不要忽视JDK的版本哦

细节决定成败。性能的根本在应用,GC参数属于微调。设置不合理,会影响性能,产生大的延时

注:配置-XX:ParallelGCThreads具体要多CPU核心数,不是越多越好。最后设置CPU核心的数量。
最后祝大家早日成为大牛!!!

 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值