sun hotspot 1.6 jvm gc ( garbage collector )

61
Sun Hotspot 1.6 JVM GC Garbage Collector http://bluedavy.com 2010-05-13 V0.2 2010-05-18 V0.5

Upload: kiet

Post on 24-Feb-2016

163 views

Category:

Documents


0 download

DESCRIPTION

Sun Hotspot 1.6 JVM GC ( Garbage Collector ) . http://bluedavy.com 2010-05-13 V0.2 2010-05-18 V 0.5. only 介绍 怎么实现的 如何 控制和使用. ppt 中未特别强调的 JVM 均指 Sun Hotspot 1.6.0. GC : Garbage Collector. 不是只负责内存回收. 还决定了内存分配. JVM 内存结构. - Xss. PC 寄存器. 本地方法栈. 局部变量区. - XX:PermSize. 操作数栈. JVM 方法区. 栈帧. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

Sun Hotspot 1.6 JVM GC ( Garbage Collector )

http://bluedavy.com2010-05-13 V0.2

2010-05-18 V0.5

Page 2: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

only 介绍怎么实现的如何控制和使用

ppt 中未特别强调的 JVM 均指 Sun Hotspot 1.6.0

Page 3: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

GC : Garbage Collector

不是只负责内存回收还决定了内存分配

Page 4: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 内存结构PC寄存器

局部变量区操作数栈

栈帧JVM 方法栈 JVM 堆

本地方法栈JVM 方法区

-Xss

-XX:PermSize

-Xms -Xmx

Page 5: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

Eden S0 S1 Old Generation

New Generation

JVM 堆:分代

SurvivorRatio

-Xmn

Page 6: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 可用 GC

串行 GC(Serial

Copying)

并行回收 GC(Parallel

Scavenge)并行 GC

(ParNew)

新生代可用的 GC

串行 GC(Serial MSC)

并行 GC(Parallel MSC)

旧生代可用的 GC并发 GC(CMS)

我该用哪个呢?

Page 7: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 新生代可用 GC— 串行找出活的对象,并基于 Copying 算法进行回收

Page 8: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 新生代可用 GC— 串行何谓活的对象?(适用于所有 GC 方式) root set 全局 / 静态变量、正在执行的方法,还有一些特殊的( VM Handle )等 这些 root set 强引用的对象 至于 Soft 、 Weak 和 Phantom 在 Full GC 时特殊处理

Soft :内存不够时一定会被 GC 、长期不用也会被 GC ,可通过 -XX:SoftRefLRUPolicyMSPerMB 来设置; Weak :一定会被 GC ,当被 mark 为 dead ,会在 ReferenceQueue 中通知; Phantom :本来就没引用,当从 jvm heap 中释放,会通知。

Page 9: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 新生代可用 GC— 串行由于只扫描新生代,此时如旧生代的对象引用了新生代的,怎么办?

在给对象赋引用时,会产生一个 write barrier ;检查是否为旧生代引用新生代,如为则记录到 remember set 中;在 minor gc 时, remember set 指向的新生代对象也作为 root set 。

Page 10: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 新生代可用 GC— 串行如何暂停应用线程?

对于每个线程执行的动作,都有一些 Safepoint ,当要进行 GC 时,则等待各线程进入 Safepoint ,进入后则将其需要才做的内存块设置为不可读,就此实现暂停应用线程。

Page 11: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 新生代可用 GC— 串行Copying 算法

关于此 PPT 中提及的算法,除特殊的实现外,均可直接参考相关的介绍自动内存管理的算法的文章,或《垃圾回收》一书。

Page 12: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 新生代可用 GC— 串行1. client 模式下默认的 GC 方式,也可使用 -XX:+UseSerialGC 强制指定;2. SurvivorRatio 是指 eden:survivor space 的比例,默认为 8 ;3. 内存分配采用 bump-the-pointer 的方式。

Page 13: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 新生代可用 GC—PS1. server 模式下默认的 GC 方式,也可使用 -XX:+UseParallelGC 强制指定;2. 在不配置 survivorRatio 时,以 InitialSurvivorRatio 为准,此值默认为 8, 代表的意思为 young space:survivor space 的比例; 也可通过 survivorRatio 强制指定,意思仍然为 eden:survivor 。 在采用 PS 时,默认情况下 JVM 会在运行时动态调整 eden:s0:s1

如不希望动态调整,可设置 -XX:-UseAdaptiveSizePolicy 参数。3. 内存分配和回收算法和串行相同,唯一的不同仅在于回收时为多线程,

PS 针对大内存新生代做了很多的优化,在参数的使用上和串行以及ParNew 有很多不同。

Page 14: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 新生代可用 GC—ParNew1. CMS GC 时默认采用,也可采用 -XX:+UseParNewGC 强制指定;2. SurvivorRatio 代表的为 eden:survivor ,默认为 8 ;3. 内存分配、回收和 PS 相同,不同的仅在于回收时会配合 CMS 做些处理。

Page 15: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 新生代 GC— 什么时候触发又称 minor GC 。1. 分配内存时 eden space 不够用;2. 默认情况下 Full GC 会先触发 minor GC ; 在 PS GC 时可通过设置 -XX:-ScavengeBeforeFullGC 来禁止先触发 minor GC 。

Page 16: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 新生代 GC— 晋升机制1. 在经历了多次 Minor GC 后仍存活,则晋升到旧生代; 可通过 -XX:MaxTenuringThreshold 设置,在 PS GC 时无效。2. Minor GC 时 To Space 空间不够,就直接往 Old 放了; 因此要特别注意是不是这个原因,导致系统频繁 Full GC 。3. 大对象、或大的数组对象,直接就在 Old 分配了; 多大的对象会在 Old 分配可通过 -XX:PretenureSizeThreshold=1024 来设置,单位为字节,默认为 0 ,此参数在 PS GC 时无效, PS GC 会自行计算来决定,什么时候分配到 old 。

Page 17: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 新生代 GC— 日志解读-verbose:gc -XX:+PrintGCDetails -Xloggc:gc.log

1. 串行 GC 版本 [GC [DefNew: 11509K->1138K(14336K), 0.0110060 secs] 11509K->1138K(38912K), 0.0112610 secs] [Times: user=0.00 sys=0.01, real=0.01 secs] 2. PS GC 版本 [GC [PSYoungGen: 11509K->1184K(14336K)] 11509K->1184K(38912K), 0.0113360 secs] [Times: user=0.03 sys=0.01, real=0.01 secs]

3. ParNew GC 版本 [GC [ParNew: 11509K->1152K(14336K), 0.0129150 secs] 11509K->1152K(38912K), 0.0131890 secs] [Times: user=0.05 sys=0.02, real=0.02 secs]

Page 18: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 新生代可用 GC— 总结1. PS 和 ParNew 方式性能更高,因此对于 server 应用而言为首选, PS 针对大的新生代区做了一些优化,例如动态调整 eden 、 s0 、 s1 的大小等;2. PS 和 ParNew 具体选择哪个,取决于旧生代用什么 GC ;3. 新生代采用的为 Copying 算法,性能通常取决于 Minor GC 时存活的对象有多少。

Page 19: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 新生代可用 GC—Demo一段这样的代码:public class Demo{

public static void main(String[] args) throws Exception{ byte[] bytes1=new byte[1024*1024*2]; byte[] bytes2=new byte[1024*1024*2]; byte[] bytes3=new byte[1024*1024*2]; bytes1=null; bytes2=null; byte[] bytes4=new byte[1024*1024*2];

Thread.sleep(5000); }}执行参数:-server –XX:+UseSerialGC –Xmn10m –Xms20M –Xmx20M

请问在执行到 byte[] bytes4 这行代码后会发生什么?如将 GC换为 PS GC 、 ParNew GC 又会发生什么?

Page 20: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 可用 GC

串行 GC(Serial

Copying)

并行回收 GC(Parallel

Scavenge)并行 GC

(ParNew)

新生代可用的 GC

串行 GC(Serial MSC)

并行 GC(Parallel MSC)

旧生代可用的 GC并发 GC(CMS)

我该用哪个呢?

Page 21: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代可用 GC— 串行1. 基于 Mark-Sweep-Compact 算法实现; Mark 为三色着色 compact 为 sliding compaction

2. Stop-the-world

3. client 方式下默认 GC 方式,可通过 -XX:+UseSerialGC 强制指定。

Page 22: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代可用 GC— 并行

Page 23: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代可用 GC— 并行1. Stop-the-world ;2. 优化点在于不是每次回收全部;3. server 模式下默认 GC 方式,可通过 -XX:+UseParallelGC 强制指定;4. 多线程并行,性能较串行好;5. 并行的线程数 cpu core<=8 ? cpu core : 3+(cpu core*5)/8 或通过 -XX:ParallelGCThreads=x 来强制指定。

Page 24: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代可用 GC— 并发1. 基于 Mark-Sweep 实现; Initial Marking ( Stop-the-world )

Concurrent MarkingPreClean ( Sun HotSpot 1.5 后引入的优化步骤)Final Marking ( Stop-the-world )

Concurrent Sweeping

2. 可通过 -XX:+UseConcMarkSweepGC 来强制指定,并发的线程数默认为 :( 并行 GC 线程数 +3)/4 ,也可通过 ParallelCMSThreads 指定;

Page 25: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代可用 GC— 并发1. Initial Marking ( Stop-the-world ) mark 下 root set 直接引用的对象2. Concurrent Marking

并发标识上面mark 出来的对象的引用; Mod Union TableMinor GC 同时进行,有可能会导致旧生代引用的对象关系改变 Card Table

旧生代中的对象引用关系也有可能改变

Page 26: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代可用 GC— 并发3. Preclean 重新扫描上一步过程中新创建的对象和引用关系改变了的对象的引 用关系; 此步什么时候执行,以及执行到什么时候再触发后续动作,取决于 两个值: -XX: CMSScheduleRemarkEdenSizeThreshold 、 -XX: CMSScheduleRemarkEdenPenetration 第一个值默认为 2 ,第二个值默认为 50% ,代表着当 eden space

使用超过 2M 时,执行此步,当使用超过 50% 时,触发 remark ; 上面这个步骤有些时候有可能会引发 bug ,有对象需要在 old 分配 空间,但由于 remark总是没执行,导致 old 空间不足,默认此步的 超时时间为 5秒,可通过 -XX: CMSMaxAbortablePrecleanTime 设置,单位为毫秒。

Page 27: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代可用 GC— 并发4. Final Marking ( Stop-the-world ) 处理 Mod Union Table 和 Card Table 中 dirty 的对象,重新 mark 。5. Concurrent Sweeping并发回收。

Page 28: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代可用 GC— 并发优缺点1. 大部分时候和应用并发进行,因此只会造成很短的暂停时间;2. 浮动垃圾,没办法, so 内存空间要稍微大一点;3. 内存碎片, -XX:+UseCMSCompactAtFullCollection 来解决;4. 争抢 CPU ,这 GC 方式就这样;5. 多次 remark ,所以总的 gc 时间会比并行的长;6. 内存分配, free list 方式, so 性能稍差,对 minor GC 会有一点影响;7. 和应用并发,有可能分配和回收同时,产生竞争,引入了锁, JVM 分配优先。

Page 29: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代可用 GC— 并发浮动垃圾 产生于 card table

Page 30: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代可用 GC— 并发1. Promotion Failed minor GC 了, to space 空间不够,往 old跑, old 也满了, so..解决方法:增大 to space ,增大 old ,或降低 cms gc 触发时机 2. Concurrent mode failure old 要分配内存了,但 old 空间不够,此时 cms gc 正在进行, so..

解决方法:增大 old ,降低 cms gc 触发的 old 所占比率。

在这两种情况下,为了安全, JVM转为触发 Full GC 。

Page 31: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代 GC— 什么时候触发1. 旧生代不够用了;2. Perm 不够用了;3. CMS GC 时出现 Promotion failed 和 Concurrent Mode failure ;

Page 32: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代 GC— 什么时候触发1. 对于 CMS GC 而言,则基于 CMSInitiatingOccupancyFraction 来决定什么时候触发,默认值为 68 ,即旧生代使用比率为 68% 时触发;2. Hotspot 还有可能根据运行状况来决定什么时候触发 CMS GC可通过设置 UseCMSInitiatingOccupancyOnly=true 来禁止

Page 33: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代 GC— 什么时候触发 [Full GC [PSYoungGen: 176K->0K(8960K)]

[PSOldGen: 6144K->6258K(10240K)] 6320K->6258K(19200K) [PSPermGen: 1685K->1685K(16384K)], 0.0065500 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Perm 也没满Old 没满

那为什么 Full GC ?

Page 34: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代 GC— 什么时候触发基于悲观原则的复杂触发策略

minor GC 时,如 old剩余空间小于之前多次 minor gc 晋升的对象的 平均值,那么就直接执行 full , ps gc 时稍有不同; 不同的地方在于 ps gc 先执行 minor gc ,执行完毕后如发现 old 剩余空间比之前晋升的对象的平均值小,那么就直接触发一次对 旧生代的收集;

Page 35: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代 GC— 日志解读1. 串行、并行方式和 Minor GC 的日志没太多差别

[Full GC [Tenured: 9216K->4210K(10240K), 0.0066570 secs] 16584K->4210K(19456K), [Perm : 1692K->1692K(16384K)], 0.0067070 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

ps: 串行方式 Full GC 时有些时候日志上可能不会有 Full GC 字样 ...

2. 并发的就复杂了[GC [1 CMS-initial-mark: 13433K(20480K)] 14465K(29696K), 0.0001830 secs] [Times: user=0.00 sys=0.00, real=0.00 secs][CMS-concurrent-mark: 0.004/0.004 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] CMS: abort preclean due to time [CMS-concurrent-abortable-preclean: 0.007/5.042 secs] [Times: user=0.00 sys=0.00, real=5.04 secs] [GC[YG occupancy: 3300 K (9216 K)][Rescan (parallel) , 0.0002740 secs][weak refs processing, 0.0000090 secs] [1 CMS-remark: 13433K(20480K)] 16734K(29696K), 0.0003710 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [CMS-concurrent-sweep: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Page 36: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代 GC— 总结1. 串行、并行都是 Stop-the-world ,要扫描整个 heap ,速度较慢,会造成应用较长时间的暂停;

例如某应用, minor gc 大概消耗 15ms ,但 full 一次就需要 500ms+ ,有些应用更是要消耗长达 2—3s 。( 1.5G Heap 、 4核 CPU 、 full 后存活大概是 300M )2. 并发是 mostly concurrent ,耗时较长,但对应用造成的暂停时间较短, 适合于对响应要求高的应用;

Page 37: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM 旧生代 GC—Demo一个例子public class Demo{

public static void main(String[] args) throws Exception{ byte[] bytes1=new byte[1024*1024*2]; byte[] bytes2=new byte[1024*1024*2]; byte[] bytes3=new byte[1024*1024*2]; byte[] bytes4=new byte[1024*1024*2];

bytes1=null; bytes2=null; bytes3=null; byte[] bytes5=new byte[1024*1024*2];

byte[] bytes6=new byte[1024*1024*2]; byte[] bytes7=new byte[1024*1024*2]; }}执行参数:-server –Xmn10M –Xms20M –Xmx20M –XX:+UseSerialGC请问以上代码执行会触发几次 minor GC 、几次 Full GC ;请问切换 GC 方式后会是什么执行状况?

Page 38: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC— 可见的未来Garbage First

超出范围,以后再扯

Page 39: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC— 默认方式新生代 GC 方式 旧生代和持久代 GC 方式

Client 串行 GC 串行 GCServer 并行回收 GC 并行 GC ( JDK 5.0 Update 6 以后)

Page 40: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC— 组合方式新生代 GC 方式 旧生代和持久代 GC 方式

-XX:+UseSerialGC 串行 GC 串行 GC-XX:+UseParallelGC 并行回收 GC 并行 GC-XX:+UseConcMarkSweepGC 并行 GC 并发 GC

当出现 concurrent Mode

failure 时采用串行 GC-XX:+UseParNewGC 并行 GC 串行 GC-XX:+UseParallelOldGC 并行回收 GC 并行 GC

-XX:+UseConcMarkSweepGC-XX:-UseParNewGC

串行 GC 并发 GC

当出现 Concurrent Mode

failure 或 promotion failed

时则采用串行 GC

不支持的组合方式 1 、 -XX:+UseParNewGC –XX:+UseParallelOldGC

2 、 -XX:+UseParNewGC –XX:+UseSerialGC

Page 41: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

GC 方式 常用参数( -Xms –Xmx –Xmn –XX:PermSize –XX:MaxPermSize )新生代可用 GC 串行 GC -XX:SurvivorRatio ,默认为 8 ,代表 eden:survivor ;

-XX:MaxTenuringThreshold ,默认为 15 ,代表对象在新生代经历多少次 minor gc 后才晋升到旧生代;

PS GC-XX:InitialSurvivorRatio ,默认为 8 ,代表 new gen:survivor ;-XX:SurvivorRatio ,默认值对于 PS GC 无效,但仍然可设置,代表 eden:survivor ;-XX:-UseAdaptiveSizePolicy ,不允许 PS GC 动态调整 eden 、 s0 、 s1 的大小;-XX:ParallelGCThreads ,设置并行 GC 的线程数。

ParNew GC-XX:SurvivorRatio ,默认为 8 ,代表 eden:survivor ;-XX:MaxTenuringThreshold ,默认为 15 ,代表对象在新生代经历多少次 minor gc 后才晋升到旧生代;

旧生代和持久代可用 GC 串行 GC 无特殊参数。并行 GC -XX:ParallelGCThreads ,设置并行 GC 的线程数。并发 GC -XX:ParallelCMSThreads ,设置并发 CMS GC 时的线程数;

-XX:CMSInitiatingOccupancyFraction ,默认 68 ,当旧生代使用比率占到多少百分比时触发CMS GC ;-XX:+UseCMSInitiatingOccupancyOnly ,默认为 false ,代表允许 hotspot根据成本来决定什么时候执行 CMS GC ;-XX:+UseCMSCompactAtFullCollection ,当 Full GC 时执行压缩;-XX:CMSMaxAbortablePrecleanTime=5000 ,设置 preclean步骤的超时时间,单位为毫秒;-XX:+CMSClassUnloadingEnabled , Perm Gen 采用 CMS GC 回收。

Page 42: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

GC 频繁,怎么办?GC 暂停时间长导致系统变慢,怎么办?

我们需要 GC Tuning !

Page 43: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

Case show first !一个真实案例,收集的信息如下:在系统运行到 67919.837秒时发生了一次 Full GC ,日志信息如下:67919.817: [GC [PSYoungGen: 588706K->70592K(616832K)] 1408209K->906379K(1472896K), 0.0197090 secs] [Times: user=0.06 sys=0.00, real=0.02 secs]67919.837: [Full GC [PSYoungGen: 70592K->0K(616832K)] [PSOldGen: 835787K->375316K(856064K)] 906379K->375316K(1472896K) [PSPermGen: 64826K->64826K(98304K)], 0.5478600 secs] [Times: user=0.55 sys=0.00, real=0.55 secs]

Page 44: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

Case show first !一个真实案例,收集的信息如下:之后 Minor GC 的信息

Page 45: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

Case show first !一个真实案例,收集的信息如下:在 68132.893 时又发生了一次 Full GC ,日志信息如下:68132.862: [GC [PSYoungGen: 594736K->63715K(609920K)] 1401225K->891090K(1465984K), 0.0309810 secs] [Times: user=0.06 sys=0.01, real=0.04 secs] 68132.893: [Full GC [PSYoungGen: 63715K->0K(609920K)] [PSOldGen: 827375K->368026K(856064K)] 891090K->368026K(1465984K) [PSPermGen: 64869K->64690K(98304K)], 0.5341070 secs] [Times: user=0.53 sys=0.00, real=0.53 secs]

之后的时间的 GC 基本也在重复上述过程。

对于这个 case ,我们该如何 Tuning 呢?

Page 46: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning1 、评估现状

2 、设定目标

3 、尝试调优4 、衡量调优

5 、细微调整

Page 47: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 衡量现状1. 衡量工具

-XX:+PrintGCDetails –XX:+PrintGCApplicationStoppedTime-Xloggc: { 文件名 } –XX:+PrintGCTimeStampsjmap (由于每个版本 jvm 的默认值可能会有改变,建议还是用 jmap首先观察下目前每个代的内存大小、 GC 方式)jstat 、 visualvm 、 sar 、 gclogviewer 系统运行状况的监测工具

2. 应收集到的信息minor gc 多久执行一次, full gc 多久执行一次,每次耗时多少?高峰期什么状况?minor gc 时回收的效果如何, survivor 的消耗状况如何,每次有多少对象会进入 old ?old 区在 full gc 后会消耗多少(简单的 memory leak判断方法)系统的 load 、 cpu消耗、 qps or tps 、响应时间

Page 48: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 设定目标调优的目标是什么呢降低 Full GC 执行频率?降低 Full GC消耗时间?降低 Full GC 所造成的应用暂停时间?降低Minor GC 执行频率?降低Minor GC消耗时间?例如某系统的 GC 调优目标:降低 Full GC 执行频率的同时,尽可能降低minor GC 的执行频率、消耗时间以及 GC 对应用造成的暂停时间。

Page 49: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 尝试调优根据目标针对性的寻找瓶颈以及制定调优策略

来说说常见的降低 Full GC 执行频率 根据前面学习到的 Full GC 触发时机,寻找到瓶颈 为什么 Full GC 执行频率高呢, old 经常满?还是 old 本来占用就高呢? old 为什么经常满呢?请参见 PPT前面的内容 ... 是不是因为 minor gc 后经常有对象进入 old呢?为什么?

注意 Java RMI 的定时 GC 触发,可通过:-XX:+DisableExplicitGC 来禁止;或通过 -Dsun.rmi.dgc.server.gcInterval=3600000 来控制触发的时间。

Page 50: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 尝试调优 降低 Full GC 执行频率 – 通常瓶颈 Old 本身占用的就一直高,所以只要稍微放点对象到 old ,就 full 了; 通常原因:缓存的东西太多 oracle 10g驱动时 preparedstatement cache太大

查找办法,很简单: dump then mat,bingo!

Page 51: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 尝试调优 降低 Full GC 执行频率 – 通常瓶颈

Minor GC 后总是有对象不断的进入 Old ,导致 Old 不断的满 通常原因: Survivor太小了 系统响应太慢、请求量太大、每次请求分配内存多 分配的对象太大 ... 查找办法: dump 这时就不是很好用了,需要的是能分析两次 minor GC之间到底哪些地方分配了内存; jstat观察 Survivor 的消耗状况, -XX:PrintHeapAtGC 输出 GC前后的详细信息; 系统响应慢那行属于系统优化,不在这里扯;

Page 52: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 尝试调优 降低 Full GC 执行频率 – 调优策略

Old 本身占用的就一直高 调优办法 ① 扩大 old 大小(减少 new 或调大 heap ); 减少 new 注意对 minor gc 的影响并且同时有可能造成 full gc 还是严重; 调大 heap 注意 full gc 的时间的延长, cpu 够强悍嘛, os 32 bit 的吗?

② 程序优化(去掉一些不必要的缓存)

Page 53: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 尝试调优 降低 Full GC 执行频率 – 调优策略

Minor GC 后总是有对象不断的进入 Old 前提:这些进入 Old 的对象在 full 时大部分都会被回收 调优办法 ① 降低Minor GC 执行频率(等到那部分再讲) ② 让对象尽量在 Minor GC 中就被回收掉 放大 new 、放大 survivor 、增大 TenuringThreshold 但要注意这些有可能会造成minor gc 执行频繁 ③ 换 CMS GC

Old 还没满就回收掉,从而降低 Full GC 触发的可能 ④ 程序优化 提升响应速度、降低每次请求分配的内存

Page 54: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 尝试调优 降低单次 Full GC 执行时间 通常原因: 旧生代太大了 ...

通常办法: 是并行 GC吗? 加点 CPU吧 升级 CPU吧 减小 Heap 或旧生代吧

Page 55: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 尝试调优 降低Minor GC 执行频率 通常原因: 每次请求分配的内存多、请求量大 通常办法: 扩大 heap 、扩大新生代、扩大 eden ,扩大时请综合考虑; 降低每次请求分配的内存; 加机器吧,分担点请求量。

Page 56: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 尝试调优 降低Minor GC 执行时间 通常原因: 新生代太大了 响应速度太慢了,导致每次 Minor GC 时存活的对象多 通常办法: 减小点新生代吧; 加点 CPU吧、升级 CPU吧; 响应能不能快点呢?

Page 57: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 算命① 当响应速度下降到多少、或请 求量上涨到多少时,系统会 挂掉?② 参数调整后系统多久会执行一次 Minor ,多久会执行一次

Full ,高峰期会如何?

Page 58: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 不是瞎算的① 系统的生辰八字 每次请求平均需要分配多少内存? 系统的平均响应时间是多少呢? 请求量是多少、多久一次 Minor 、 Full ?② 先掐指算下 在现在的参数下,应该是多久一次 Minor 、 Full ,对比真实状况,做一定 的偏差;③ 根据所掌握的知识,就可以判断了

Page 59: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 来算一卦

Page 60: Sun Hotspot 1.6 JVM GC ( Garbage Collector )

JVM GC Tuning— 总结 是个复杂过程,按照 Tony ( GC主要作者的说法): GC Tuning is art!

pls综合考虑,每个参数的调整都有可能带来其他的影响。 总结来说,提升响应速度、降低每次请求分配的内存才是必杀技! 或者不计成本: 64 bit ,多个高档 CPU 、大量的内存都上!