Sun JDK 1.6内存管理使用篇
毕玄
2010-10、2010-11
目标
• 掌握Sun JDK内存区域是如何划分和使用的
• 掌握Sun JDK有哪些GC,怎么用,什么时候触发
• 掌握OOM的解决方法
• 掌握如何监测GC的状况
内存管理
• Explicit (例如C)
– 分配内存:malloc
– 释放内存:free
• 优点
– 高效
• 缺点
– 开发成本高
内存管理
• Auto(例如Lisp、Java、.net、erLang)
– 语言本身来负责内存的分配和回收
• 优点
– 开发效率高
– 避免内存分配bug
• 缺点
– 不可预期的latency
内存管理
• Java
– Garbage Collector
• Memory Allocate
• Memory Free– Garbage Collection
– Garbage: 没有被引用的对象
»如忘记释放应该释放的
引用,就会
造成memory leak
Sun JDK Memory Area
PC寄存器
局部变量区
操作数栈
栈帧
方法栈 堆
本地方法栈
方法区
-Xss
-XX:PermSize –XX:MaxPermSize
-Xms -Xmx
备注:在Sun JDK中本地方法栈和方法栈是同一个,因此也可用-Xss控制
Sun JDK Memory Area
• 方法栈 & 本地方法栈
– 线程创建时产生,方法执行时生成栈帧;
• 方法区
– 存储类的元数据信息、常量等;
• 堆
– Java代码中所有的new操作;
• Native Memory(C Heap)
– Direct ByteBuffer、JNI、Compile、GC;
堆
Eden S0 S1 Old Generation
New Generation
-XX:SurvivorRatio
-Xmn
备注:通常将对新生代进行的回收称为Minor GC或Young GC;对旧生代进行的回收称为Major GC,但由于Major GC除并发GC外均需对整个堆以及持久代进行扫描和回收,因此又称为Full GC。
目标
• 掌握Sun JDK内存区域是如何划分和使用的
• 掌握Sun JDK有哪些GC,怎么用,什么时候触发
• 掌握OOM的解决方法
• 掌握如何监测GC的状况
Garbage Collector
• Serial
• Parallel
– YGC: Parallel Scavenge(PS)
– FGC: Parallel MSC(PSOld),Parallel Compacting(ParOld)
• Concurrent
– YGC: ParNew
– FGC: CMS,fail then Serial MSC
Garbage Collector - Serial
• Client模式下默认;
• 可用-XX:+UseSerialGC强制使用。
• 优点
– 对于Server应用而言,没看出有什么优点
• 缺点
– 慢,不能充分发挥硬件资源
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请从这里下载
Garbage Collector - Serial
• 内存回收触发时发生了什么– YGC
• 清空eden+from中所有no ref的对象占用的内存;• 将eden+from中所有存活的对象copy到to中;• 在这个过程中一些对象将晋升到old中;
– to放不下的;– 存活次数超过tenuring threshold的。
• 重新计算Tenuring Threshold;• 单线程做以上所有动作;• 全过程暂停应用。
• 怎么看各个区域内存的变化:jstat –gcutil 或gc log• Case Show!
Garbage Collector - Serial
• 内存回收触发时发生了什么
– FGC
• 如配置了CollectGen0First,则先触发YGC;
• 清空heap中no ref的对象,permgen中已经被卸载的classloader中加载的class的信息;
• 单线程做以上所有动作;
• 全过程暂停应用。
• Case Show!
Garbage Collector - Serial
• 细节参数
– -XX:SurvivorRatio=x,控制eden/s0/s1的大小;
– -XX:MaxTenuringThreshold,用于控制对象在新生代存活的最大次数;
– -XX:PretenureSizeThreshold=x,控制超过多大字节的对象就在old上分配;
• Case Show!
Garbage Collector - Parallel
• Server模式下默认;– YGC: PS FGC: Parallel MSC
• 可用-XX:+UseParallelGC或-XX:+UseParallelOldGC来强制指定;– ParallelGC代表FGC为Parallel MSC– ParallelOldGC代表FGC为Parallel Compacting
• 优点– 高效;
• 缺点– 当heap变大后,造成的暂停时间会变得比较长。
Garbage Collector - Parallel
• 内存回收触发机制– YGC
• eden空间不足;
– FGC• old空间不足;• perm空间不足;• 显示调用System.gc(),包括RMI等的定时触发;• YGC时的悲观策略;
– YGC前 & YGC后
• dump live的内存信息时(jmap –dump:live) 。
• Case Show!
Garbage Collector - Parallel
• 内存回收触发时发生了什么
– YGC
• 和Serial所作的动作基本相同,不同的为多线程在做这些动作;
• 另一步不同的动作为在YGC的最后不仅重新计算Tenuring Threshold,还会重新调整Eden和From的大小。
• Case Show!
Garbage Collector - Parallel
• 内存回收触发时发生了什么– FGC
• 如配置了ScavengeBeforeFullGC(默认),则先触发YGC;
• MSC: 清空heap中no ref的对象,permgen中已经被卸载的classloader中加载的class的信息,并进行压缩;
• Compacting: 清空heap中部分no ref的对象, permgen中已经被卸载的classloader中加载的class的信息,并进行部分压缩;
• 多线程做以上动作。
• Case Show!
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!
Garbage Collector - Concurrent
• 可用-XX:+UseConcMarkSweepGC来强制指定;
• 优点– 在对Old进行回收时,对应用造成的暂停时间非常短,适合对latency要求高的应用;
• 缺点– 内存碎片和浮动垃圾;
– Old区上的内存分配效率低;
– 回收的整个耗时比较长;
– 和应用争抢CPU;
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!
Garbage Collector - Concurrent
• 内存回收触发时发生了什么– YGC
• 和Serial动作完全相同,只是改为了采用多线程;
– CMS GC• old gen到达比率时只清除old gen中no ref的对象所占用的空间;
• perm gen到达比率时只清除已被清除的classloader加载的class信息;
– FGC• 和Serial动作完全相同。
• Case Show!
Garbage Collector - Concurrent
• 细节参数– -XX:CMSInitiatingOccupancyFraction,设置Old
Gen使用到达多少比率时触发;
– -XX:CMSInitiatingPermOccupancyFraction,设置Perm Gen使用到达多少比率时触发;
– -XX:+UseCMSInitiatingOccupancyOnly ,禁止hotspot自行触发CMS GC;
• Case Show!
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
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
目标
• 掌握Sun JDK内存区域是如何划分和使用的
• 掌握Sun JDK有哪些GC,怎么用,什么时候触发
• 掌握OOM的解决方法
• 掌握如何监测GC的状况
Memory Monitoring
• 内存使用情况
– Heap & PermGen
• jstat –gc or jstat –gcutil
• jmap –heap
– C Heap
• top or ps aux
Memory Monitoring
• 谁用了内存
– Heap
• jmap –histo
• jmap –dump,then mat
– C Heap
• google perftools
Memory Monitoring
• GC的状况
– YGC/FGC的频率、耗时、回收的效果
• jstat –gcutil
• -XX:+PrintGCDetails –XX:+PrintGCDateStamps –Xloggc:<file>
常见问题
• OOM
– Cases Show!
1、java -Xms20m -Xmx20m -Xmn10m -XX:+UseParallelGCcom. bluedavy.oom.JavaHeapSpaceCase1
2、java -Xms20m -Xmx20m -Xmn10m -XX:+HeapDumpOnOutOfMemoryErrorcom.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
常见问题
• OOM Solution Pattern– Java Heap Space
• 是不是heap太小了呢?• -XX:+HeapDumpOnOutOfMemoryError;• jmap –histo多看几次;• jmap –dump;• 再不行就人肉。
– Out of Swap• 堆开太大了?• google perftools
– unable to create new native thread• 线程太多了? -Xss太大了?
– PermGen Space• permgen太小了?• ClassLoader太多了?泄露?
常见问题
• Write OOM Friendly Code
– 限制List/Set/Map/StringBuilder等的大小;
– 避免死循环;
常见问题
• 长暂停
– 应用调优 or GC Tuning
• 详细请见调优篇。
• GC占了应用运行的很多时间
– 同上
• Case Show!
目标
• 掌握Sun JDK内存区域是如何划分和使用的
• 掌握Sun JDK有哪些GC,怎么用,什么时候触发
• 掌握OOM的解决方法
• 掌握如何监测GC的状况
References
• Sun JDK Memory Management whitepaper
• 老外正在写的一个OOM系列的文章
• 两个OOM Cases排查过程的分享
• 一个GC频繁的Case