文章目录
堆的回顾
1、堆中分为新生代和老年代。如图:eden、s0、s1为新生代区域,tenured为老年代区域。s0、s1是两个大小相等的区域,称为幸存区,该区域使用的复制算法。
串行收集器
串行收集器是GC中常用的一种收集器。
1、其最古老、最稳定
2、效率高
3、可能会产生较长的停顿
4、使用参数 -XX:+UseSerialGC
启动串行收集器,使用该参数:
- 新生代、老年代使用串行回收。
- 新生代使用复制算法。
- 老年代使用标记-压缩算法。
-
启动串行收集器,GC单线程运行,应用程序线程暂停。
并行收集器
一、新生代收集器ParNew
1、简称:ParNew ,并行收集器参数-XX:+UseParNewGC
,启动后,新生代并行,老年代串行,会影响新生代的回收,对老年代没有影响。
2、新生代依然采用复制算法。
3、支持多线程,需要多核支持。
4、参数:-XX:ParallelGCThreads
,可以设置线程的数量。
启用ParNew并行收集器,应用程序暂停,GC线程并发运行。
二、Parallel 收集器
类似于ParNew,新生代采用复制算法,老年代采用标记-压缩算法,更加关注吞吐量,新生代并行。
1、参数设置:-XX:+UseParallelGC
,使用Parallel收集器 + 老年代串行。
2、-XX:+UseParallelOldGC
,使用Parallel收集器 + 并行老年代。
并行收集器中的两个参数
1、-XX:MaxGCPauseMills
- 最大停顿时间,单位毫秒;GC将尽力保证回收时间不超过设定值。
2、-XX:GCTimeRatio
- 该参数的取值范围为0-100,表示垃圾收集时间占总时间的比,默认为99,即最大允许1%时间做GC。
以上两个参数时矛盾的,因为停顿时间和吞吐量不可能同时调优。
CMS收集器
csm收集器,全程Concurrent Mark Sweep 并发标记清除,采用的标记清除算法,与标记压缩算法相比,并发阶段会降低吞吐量,属于老年代收集器(新生代使用ParNew),参数-XX:+UseConcMarkSweepGC
。
1、CMS收集器运行过程比较复杂,着重实现了标记的过程,可分为:
- 初始标记(根可以直接关联到的对象,速度快)。
- 并发标记(和用户线程一起,主要标记过程,标记全部对象)
- 重新标记(由于并发标记时,用户线程依然运行,因此在正式清理前,再做修正)。
- 并发清除(和用户线程一起,基于标记结果,直接清理对象)。
CMS收集器在对应用对象做处理时,初始标记是,GC是单线程运行,在并发标记时,GC和应用线程并发运行,重新标记时GC单线程运行,并发清理时,GC和应用线程并发运行。
CMS收集器的特点
1、尽可能的降低停顿。
2、会影响系统整体吞吐量和性能。
- 比如,在用户线程运行过程中,分一半CPU去做GC,系统性能在GC阶段,反应速度就下降一半。
3、清理不彻底
- 因为在清理阶段,用户线程还在运行,会产生新的垃圾,无法清理。
4、因为和用户线程一起运行,不能在空间快满时再清理。
- 参数:
-XX:CMSInitatingOccupancyFraction
设置触发GC的阈值,表示当推空间占用多少时,自动触发GC执行。 - 如果不幸内存预留空间不够时,就会引起concurrent mode failure。
2、 标记清除和标记压缩的对比
标记清除和标记压缩的对比,标记清除之后会产生碎片空间,会影响对象的存储,标记压缩经过清理之后,是连续的空间。而标记压缩清理之后,对于存活的对象的位置会产生移动,应用程序会找不到对象。
3、CMS的参数整理
1、-XX:+UseCMSCompactAtFullCollection
在每一次Full GC之后,进行一次整理,整理过程是独占的,会引起停顿时间变长。
2、-XX:+CMSFullGCsBeforeCompaction
,设置进行几次Full GC后,进行一次碎片整理。
3、-XX:ParallelCMSThreads
,设置CMS的线程数量。
为减轻GC压力,我们需要注意什么?
从以下三个方面提高应用程序性能:
1、软件如何设计架构。
2、代码如何写。
3、堆空间如何分配。
GC参数整理
1、-XX:+UseSerialGC
:在新生代和老年代使用串行收集器。
2、-XX:SurvivorRatio
:设置eden去大小和survivior区大小的比例。
3、-XX:NewRatio
:设置新生代和老年代的比例。
4、-XX:+UseParNewGC
:在新生代使用并行收集器。
5、-XX:+UseParallelGC
:新生代使用Parallel收集器,老年代串行。
6、-XX:+UseParallelOldGC
:老年代使用并行回收收集器。
7、-XX:ParallelGCThreads
:设置Parallel收集器,用于垃圾回收的线程数。
8、-XX:+UseConcMarkSweepGC
:新生代使用并行收集器,老年代使用CMS+串行收集器。
9、-XX:ParallelCMSThreads:
设定CMS的线程数量。
10、-XX:CMSInitiatingOccupancyFraction
:设置CMS收集器在老年代空间被使用多少后触发。
11、-XX:+UseCMSCompactAtFullCollection:设置CMS收集器在完成垃圾收集后是否要进行一次内存碎片的整理。
12、-XX:CMSFullGCsBeforeCompaction
:设定进行多少次CMS垃圾回收后,进行一次内存压缩。
13、-XX:+CMSClassUnloadingEnabled
:允许对类元数据进行回收。
14、-XX:CMSInitiatingPermOccupancyFraction
:当永久区占用率达到这一百分比时,启动CMS回收。
15、-XX:UseCMSInitiatingOccupancyOnly
:表示只在到达阈值的时候,才进行CMSS回收。
Tomcat实例
测试程序运行时,GC垃圾回收器各个参数对Tomcat的影响。
1、环境
- Tomcat7
- JSP网站
- 测试网站吞吐量
2、工具 - JMeter
3、目的 - 让Tomcat有一个不错的吞吐量。
系统结构
tomcat在服务器上,JMeter在另一台计算机上,不能运行在同一台计算机上,防止JMeter对Tomcat的运行产生的影响。
将参数设置在Tomcat中bin下的Catalina.bat中。
测试一、使用32M堆处理请求
测试二、使用最大堆512M处理请求
测试三、设置最小堆为64M,GC次数减少。
测试四、使用并行回收器
测试五、减小堆内存,没设置,默认为串行收集器
测试六:使用并行收集器
测试七、使用新生代收集器
测试八、使用jdk6,不使用任何参数
测试九、使用jdk7,不使用任何参数。
最后送给大家一句话,细节决定成败!!!
性能的好坏根本在于应用,GC参数只是在应用的基础上做出一些微调。在一个好的应用上面,进行参数设置,将起到事半功倍的效果。参数设置不合理,会影响性能,产生大的延时。