sun jdk 1.6内存管理 -使用篇
DESCRIPTION
TRANSCRIPT
目标• 掌握 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 – Concurrent1
• 可用 -XX:+UseConcMarkSweepGC 来强制指定;• 优点
– 在对 Old 进行回收时,对应用造成的暂停时间非常短,适合对 latency 要求高的应用;
• 缺点– 内存碎片和浮动垃圾;– Old 区上的内存分配效率低;– 回收的整个耗时比较长;– 和应用争抢 CPU ;
1. jdk 6.0 update 23 以前的版本中有一些会导致 crash 的 bug: 6872049,6948538,6948539
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:+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
常见问题• 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
常见问题• 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系列的文章