sun jdk 1.6内存管理 -使用篇

36
Sun JDK 1.6 内内内内 内内内 bluedavy 2010-10 2010-11

Upload: bluedavy-lin

Post on 15-Jan-2015

11.591 views

Category:

Technology


2 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Sun jdk 1.6内存管理 -使用篇

Sun JDK 1.6 内存管理使用篇bluedavy

2010-10 、 2010-11

Page 2: Sun jdk 1.6内存管理 -使用篇

目标• 掌握 Sun JDK 内存区域是如何划分和使用的• 掌握 Sun JDK 有哪些 GC ,怎么用,什么时

候触发• 掌握 OOM 的解决方法• 掌握如何监测 GC 的状况

Page 3: Sun jdk 1.6内存管理 -使用篇

内存管理• Explicit ( 例如 C)

– 分配内存: malloc– 释放内存: free

• 优点– 高效

• 缺点– 开发成本高

Page 4: Sun jdk 1.6内存管理 -使用篇

内存管理• Auto( 例如 Lisp 、 Java 、 .net 、 erLang)

– 语言本身来负责内存的分配和回收• 优点

– 开发效率高– 避免内存分配 bug

• 缺点– 不可预期的 latency

Page 5: Sun jdk 1.6内存管理 -使用篇

内存管理• Java

– Garbage Collector• Memory Allocate• Memory Free

– Garbage Collection– Garbage: 没有被引用的对象

» 如忘记释放应该释放的 引用,就会 造成 memory leak

Page 6: Sun jdk 1.6内存管理 -使用篇

Sun JDK Memory Area

PC 寄存器

局部变量区

操作数栈

栈帧

方法栈 堆

本地方法栈

方法区

-Xss

-XX:PermSize –XX:MaxPermSize

-Xms -Xmx

备注:在 Sun JDK 中本地方法栈和方法栈是同一个,因此也可用 -Xss 控制

Page 7: Sun jdk 1.6内存管理 -使用篇

Sun JDK Memory Area

• 方法栈 & 本地方法栈– 线程创建时产生,方法执行时生成栈帧;

• 方法区– 存储类的元数据信息、常量等;

• 堆– Java 代码中所有的 new 操作;

• Native Memory(C Heap)– Direct ByteBuffer 、 JNI 、 Compile 、 GC ;

Page 8: Sun jdk 1.6内存管理 -使用篇

Eden S0 S1 Old Generation

New Generation

-XX:SurvivorRatio

-Xmn

备注:通常将对新生代进行的回收称为 Minor GC 或 Young GC ;对旧生代进行的回收称为 Major GC ,但由于Major GC 除并发 GC 外均需对整个堆以及持久代进行扫描和回收,因此又称为 Full GC 。

Page 9: Sun jdk 1.6内存管理 -使用篇

目标• 掌握 Sun JDK 内存区域是如何划分和使用的• 掌握 Sun JDK 有哪些 GC ,怎么用,什么时

候触发• 掌握 OOM 的解决方法• 掌握如何监测 GC 的状况

Page 10: Sun jdk 1.6内存管理 -使用篇

Garbage Collector

• Serial• Parallel

– YGC: Parallel Scavenge(PS)– FGC: Parallel MSC(PSOld),Parallel

Compacting(ParOld)• Concurrent

– YGC: ParNew– FGC: CMS,fail then Serial MSC

Page 11: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Serial

• Client 模式下默认;• 可用 -XX:+UseSerialGC 强制使用。• 优点

– 对于 Server 应用而言,没看出有什么优点• 缺点

– 慢,不能充分发挥硬件资源

Page 12: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Serial

• 内存回收触发机制– YGC

• eden 空间不足;– FGC

• old 空间不足;• perm 空间不足;• 显示调用 System.gc() ,包括 RMI 等的定时触发 ;• YGC 时的悲观策略;• dump live 的内存信息时 (jmap –dump:live) 。

• 怎么看有没有触发: jstat 或 gc log• Case Show!1

1. case 请从这里下载

Page 13: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Serial

• 内存回收触发时发生了什么– YGC

• 清空 eden+from 中所有 no ref 的对象占用的内存;• 将 eden+from 中所有存活的对象 copy 到 to 中;• 在这个过程中一些对象将晋升到 old 中;

– to 放不下的;– 存活次数超过 tenuring threshold 的。

• 重新计算 Tenuring Threshold ;• 单线程做以上所有动作;• 全过程暂停应用。

• 怎么看各个区域内存的变化: jstat –gcutil 或 gc log• Case Show!

Page 14: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Serial

• 内存回收触发时发生了什么– FGC

• 如配置了 CollectGen0First ,则先触发 YGC ;• 清空 heap 中 no ref 的对象, permgen 中已经被卸载

的 classloader 中加载的 class 的信息;• 单线程做以上所有动作;• 全过程暂停应用。

• Case Show!

Page 15: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Serial

• 细节参数– -XX:SurvivorRatio=x ,控制 eden/s0/s1 的大小;– -XX:MaxTenuringThreshold ,用于控制对象在新

生代存活的最大次数;– -XX:PretenureSizeThreshold=x ,控制超过多大字

节的对象就在 old 上分配;

• Case Show!

Page 16: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Parallel

• Server 模式下默认;– YGC: PS FGC: Parallel MSC

• 可用 -XX:+UseParallelGC 或 -XX:+UseParallelOldGC来强制指定;– ParallelGC 代表 FGC 为 Parallel MSC– ParallelOldGC 代表 FGC 为 Parallel Compacting

• 优点– 高效;

• 缺点– 当 heap 变大后,造成的暂停时间会变得比较长。

Page 17: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Parallel

• 内存回收触发机制– YGC

• eden 空间不足;– FGC

• old 空间不足;• perm 空间不足;• 显示调用 System.gc() ,包括 RMI 等的定时触发 ;• YGC 时的悲观策略;

– YGC 前 & YGC 后• dump live 的内存信息时 (jmap –dump:live) 。

• Case Show!

Page 18: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Parallel

• 内存回收触发时发生了什么– YGC

• 和 Serial 所作的动作基本相同,不同的为多线程在做这些动作;

• 另一步不同的动作为在 YGC 的最后不仅重新计算Tenuring Threshold ,还会重新调整 Eden 和 From 的大小。

• Case Show!

Page 19: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Parallel

• 内存回收触发时发生了什么– FGC

• 如配置了 ScavengeBeforeFullGC( 默认 ) ,则先触发 YGC ;• MSC: 清空 heap 中 no ref 的对象, permgen 中已经被卸载

的 classloader 中加载的 class 的信息,并进行压缩;• Compacting: 清空 heap 中部分 no ref 的对象, permgen 中

已经被卸载的 classloader 中加载的 class 的信息,并进行部分压缩;

• 多线程做以上动作。

• Case Show!

Page 20: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Parallel

• 细节参数– -XX:SurvivorRatio=x ,控制 eden/s0/s1 的大小,含

义为 eden:survivor space ;– -XX:MaxTenuringThreshold ,用于控制对象在新生代

存活的最大次数;– -XX:-UseAdaptiveSizePolicy ,去掉 YGC 后动态调整

eden 、 from 以及 tenuring threshold 的动作;– -XX:ParallelGCThreads ,设置并行的线程数;

• Case Show!

Page 21: Sun jdk 1.6内存管理 -使用篇

Garbage Collector – Concurrent1

• 可用 -XX:+UseConcMarkSweepGC 来强制指定;• 优点

– 在对 Old 进行回收时,对应用造成的暂停时间非常短,适合对 latency 要求高的应用;

• 缺点– 内存碎片和浮动垃圾;– Old 区上的内存分配效率低;– 回收的整个耗时比较长;– 和应用争抢 CPU ;

1. jdk 6.0 update 23 以前的版本中有一些会导致 crash 的 bug: 6872049,6948538,6948539

Page 22: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Concurrent

• 内存回收触发机制– YGC

• eden 空间不足;– CMS GC

• Old Gen 的使用到达一定的比率,默认为 92% ;• 配置了 CMSClassUnloadingEnabled ,且 Perm Gen 的使用到达一定的

比率,默认为 92% ;• Hotspot自己根据估计决定是否要触发;• 在配置了 ExplicitGCInvokesConcurrent 的情况下显示调用了

System.gc 。– Full GC(Serial MSC)

• Promotion Failed 或 Concurrent Mode Failure 时;• Case Show!

Page 23: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Concurrent

• 内存回收触发时发生了什么– YGC

• 和 Serial 动作完全相同,只是改为了采用多线程;– CMS GC

• old gen 到达比率时只清除 old gen 中 no ref 的对象所占用的空间;

• perm gen 到达比率时只清除已被清除的 classloader 加载的 class 信息;

– FGC• 和 Serial 动作完全相同。

• Case Show!

Page 24: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Concurrent

• 细节参数– -XX:CMSInitiatingOccupancyFraction ,设置 Old

Gen 使用到达多少比率时触发;– -XX:CMSInitiatingPermOccupancyFraction ,设置

Perm Gen 使用到达多少比率时触发;– -XX:+UseCMSInitiatingOccupancyOnly ,禁止

hotspot自行触发 CMS GC ;

• Case Show!

Page 25: Sun jdk 1.6内存管理 -使用篇

Garbage Collector - Summary• import java.util.*;• public class SummaryCase{• public static void main(String[] args) {• List<Object> caches=new ArrayList<Object>();• for(int i=0;i<7;i++){• caches.add(new byte[1024*1024*3]);• }• caches.clear();• for(int i=0;i<2;i++){• caches.add(new byte[1024*1024*3]);• }• }• }• 用以下两种参数执行,会执行几次 minor gc 和几次 full gc呢?• -Xms30m -Xmx30m -Xmn10m -XX:+UseParallelGC• -Xms30m -Xmx30m -Xmn10m -XX:+UseSerialGC

Page 26: Sun jdk 1.6内存管理 -使用篇

Garbage Collector – Future

• Garbage First (G1)– JDK 1.6 update 14 or JDK 7– Few flags need to set

• -XX:MaxGCPauseMillis=100 -XX:GCPauseIntervalMillis=6000

Page 27: Sun jdk 1.6内存管理 -使用篇

目标• 掌握 Sun JDK 内存区域是如何划分和使用的• 掌握 Sun JDK 有哪些 GC ,怎么用,什么时

候触发• 掌握 OOM 的解决方法• 掌握如何监测 GC 的状况

Page 28: Sun jdk 1.6内存管理 -使用篇

Memory Monitoring

• 内存使用情况– Heap & PermGen

• jstat –gc or jstat –gcutil• jmap –heap

– C Heap• top or ps aux

Page 29: Sun jdk 1.6内存管理 -使用篇

Memory Monitoring

• 谁用了内存– Heap

• jmap –histo• jmap –dump,then mat

– C Heap• google perftools

Page 30: Sun jdk 1.6内存管理 -使用篇

Memory Monitoring

• GC 的状况– YGC/FGC 的频率、耗时、回收的效果

• jstat –gcutil• -XX:+PrintGCDetails –XX:+PrintGCDateStamps –

Xloggc:<file>

Page 31: Sun jdk 1.6内存管理 -使用篇

常见问题• OOM

– Cases Show!1 、 java -Xms20m -Xmx20m -Xmn10m -XX:+UseParallelGC

com. bluedavy.oom.JavaHeapSpaceCase1

2 、 java -Xms20m -Xmx20m -Xmn10m -XX:+HeapDumpOnOutOfMemoryError com.bluedavy.oom.JavaHeapSpaceCase2

3 、同上的启动参数执行 com.bluedavy.oom.JavaHeapSpaceCase3

4 、同上的启动参数执行 com.bluedavy.oom.JavaHeapSpaceCase4

5 、 java -Xms1536m -Xmx1536m -Xss100m com.bluedavy.oom.CannotCreateThreadCase

6 、 java –Xmn10m –Xms1536m –Xmx1536m NativeMemoryOOMCase

Page 32: Sun jdk 1.6内存管理 -使用篇

常见问题• OOM Solution Pattern

– Java Heap Space• 是不是 heap太小了呢?• -XX:+HeapDumpOnOutOfMemoryError;• jmap –histo 多看几次;• jmap –dump1 ;• 再不行就人肉。

– Out of Swap• 堆开太大了?• google perftools

– unable to create new native thread• 线程太多了? -Xss太大了?

– PermGen Space• permgen太小了?• ClassLoader太多了?泄露?

1. jdk 6.0 update 23 以前的版本中有这个 bug: http://goo.gl/nmTB8

Page 33: Sun jdk 1.6内存管理 -使用篇

常见问题• Write OOM Friendly Code

–限制 List/Set/Map/StringBuilder 等的大小;– 避免死循环;

Page 34: Sun jdk 1.6内存管理 -使用篇

常见问题• 长暂停

– 应用调优 or GC Tuning• 详细请见调优篇。

• GC 占了应用运行的很多时间– 同上

• Case Show!

Page 35: Sun jdk 1.6内存管理 -使用篇

目标• 掌握 Sun JDK 内存区域是如何划分和使用的• 掌握 Sun JDK 有哪些 GC ,怎么用,什么时

候触发• 掌握 OOM 的解决方法• 掌握如何监测 GC 的状况

Page 36: Sun jdk 1.6内存管理 -使用篇

References

• Sun JDK Memory Management whitepaper• 老外正在写的一个OOM系列的文章