• 1. 分布式Java应用系列培训林昊 http://blog.bluedavy.com
  • 2. Just a travel传统的单机应用小型分布式应用中型分布式应用大型分布式应用
  • 3. 高性能要求要写出高性能的Java程序,要对JVM有所了解: Java代码执行; Java内存管理。
  • 4. Java代码执行Java源码Java Class装载Class解释执行C1 or C2编译执行
  • 5. Java代码执行Java源码  Java Class Sun: javac 常量折叠、解除语法糖等; 优化这步编译是没有太大意思的。 -g:none会导致compile出来的class缺少行号,严重影响调试; javap –c –s –l –verbose [Class]来查看class文件。
  • 6. Java代码执行Java Class  装载Class ClassLoader来加载; Bootstrap(-Xbootclasspath) – Extension(java.ext.dirs) – Endorsed – Classpath(-classpath) – User Custom 想知道类是从哪个jar包里加载的吗? 启动参数上加上-XX:+TraceClassLoading
  • 7. Java代码执行装载Class  解释执行 基于栈的体系; 基本方法:FDX; 优化的种种:switched/token/inline; 栈顶cache; 超级指令; 启动速度快、执行速度慢。
  • 8. Java代码执行解析执行  c1 or c2编译(JIT)执行 Client模式下: c1,Server模式下:c2 触发条件 方法执行次数(-XX:CompileThreshold); Client: 1500 Server:10000 方法内循环执行次数。 触发OSR编译 c1 Vs c2 Inline是关键; c2收集profile信息,以便做高级优化; 标量替换/EA/锁消除/增大锁粒度 -XX:+PrintCompilation 6u25中已经带有了多层编译。
  • 9. 内存管理Explicit (例如C) 分配内存:malloc 释放内存:free 优点 高效 缺点 开发成本高
  • 10. 内存管理Auto(例如Lisp、Java、.net、erLang) 语言本身来负责内存的分配和回收 优点 开发效率高 避免内存分配bug 缺点 不可预期的latency
  • 11. 内存管理Java Garbage Collector Memory Allocate Memory Free Garbage Collection Garbage: 没有被引用的对象 如忘记释放应该释放的 引用,就会 造成memory leak
  • 12. Sun JDK Memory AreaPC寄存器局部变量区操作数栈栈帧方法栈堆本地方法栈方法区-Xss-XX:PermSize –XX:MaxPermSize-Xms -Xmx备注:在Sun JDK中本地方法栈和方法栈是同一个,因此也可用-Xss控制
  • 13. Sun JDK Memory Area方法栈 & 本地方法栈 线程创建时产生,方法执行时生成栈帧; 方法区 存储类的元数据信息、常量等; 堆 Java代码中所有的new操作; Native Memory(C Heap) Direct ByteBuffer、JNI、Compile、GC;
  • 14. 堆EdenS0S1Old GenerationNew Generation-XX:SurvivorRatio-Xmn备注:通常将对新生代进行的回收称为Minor GC或Young GC;对旧生代进行的回收称为Major GC,但由于 Major GC除并发GC外均需对整个堆以及持久代进行扫描和回收,因此又称为Full GC。
  • 15. Garbage CollectorSerial 串行 Parallel 并行 YGC: Parallel Scavenge(PS) FGC: Parallel MSC(PSOld),Parallel Compacting(ParOld) Concurrent 并发 YGC: ParNew FGC: CMS,fail then Serial MSC
  • 16. Garbage Collector - SerialClient模式下默认; 可用-XX:+UseSerialGC强制使用。 优点 对于Server应用而言,没看出有什么优点 缺点 慢,不能充分发挥硬件资源
  • 17. Garbage Collector - Serial内存回收触发机制 YGC eden空间不足; FGC old空间不足; perm空间不足; 显示调用System.gc() ,包括RMI等的定时触发; YGC时的悲观策略; dump live的内存信息时(jmap –dump:live)。 怎么看有没有触发:jstat 或gc log Case Show!11. case请从这里下载
  • 18. Garbage Collector - Serial内存回收触发时发生了什么 YGC 清空eden+from中所有no ref的对象占用的内存; 将eden+from中所有存活的对象copy到to中; 在这个过程中一些对象将晋升到old中; to放不下的; 存活次数超过tenuring threshold的。 重新计算Tenuring Threshold; 单线程做以上所有动作; 全过程暂停应用。 怎么看各个区域内存的变化:jstat –gcutil 或gc log Case Show!
  • 19. Garbage Collector - Serial内存回收触发时发生了什么 FGC 如配置了CollectGen0First,则先触发YGC; 清空heap中no ref的对象,permgen中已经被卸载的classloader中加载的class的信息; 单线程做以上所有动作; 全过程暂停应用。 Case Show!
  • 20. Garbage Collector - Serial细节参数 -XX:SurvivorRatio=x,控制eden/s0/s1的大小; -XX:MaxTenuringThreshold,用于控制对象在新生代存活的最大次数; -XX:PretenureSizeThreshold=x,控制超过多大字节的对象就在old上分配; Case Show!
  • 21. Garbage Collector - ParallelServer模式下默认; YGC: PS FGC: Parallel MSC 可用-XX:+UseParallelGC或-XX:+UseParallelOldGC来强制指定; ParallelGC代表FGC为Parallel MSC ParallelOldGC代表FGC为Parallel Compacting 优点 高效; 缺点 当heap变大后,造成的暂停时间会变得比较长。
  • 22. Garbage Collector - Parallel内存回收触发机制 YGC eden空间不足; FGC old空间不足; perm空间不足; 显示调用System.gc(),包括RMI等的定时触发; YGC时的悲观策略; YGC前 & YGC后 dump live的内存信息时(jmap –dump:live) 。 Case Show!
  • 23. Garbage Collector - Parallel内存回收触发时发生了什么 YGC 和Serial所作的动作基本相同,不同的为多线程在做这些动作; 另一步不同的动作为在YGC的最后不仅重新计算Tenuring Threshold,还会重新调整Eden和From的大小。 Case Show!
  • 24. Garbage Collector - Parallel内存回收触发时发生了什么 FGC 如配置了ScavengeBeforeFullGC(默认),则先触发YGC; MSC: 清空heap中no ref的对象,permgen中已经被卸载的classloader中加载的class的信息,并进行压缩; Compacting: 清空heap中部分no ref的对象, permgen中已经被卸载的classloader中加载的class的信息,并进行部分压缩; 多线程做以上动作。 Case Show!
  • 25. 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!
  • 26. Garbage Collector - Concurrent可用-XX:+UseConcMarkSweepGC来强制指定; 优点 在对Old进行回收时,对应用造成的暂停时间非常短,适合对latency要求高的应用; 缺点 内存碎片和浮动垃圾; Old区上的内存分配效率低; 回收的整个耗时比较长; 和应用争抢CPU;
  • 27. 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!
  • 28. Garbage Collector - Concurrent内存回收触发时发生了什么 YGC 和Serial动作完全相同,只是改为了采用多线程; CMS GC old gen到达比率时只清除old gen中no ref的对象所占用的空间; perm gen到达比率时只清除已被清除的classloader加载的class信息; FGC 和Serial动作完全相同。 Case Show!
  • 29. Garbage Collector - Concurrent细节参数 -XX:CMSInitiatingOccupancyFraction,设置Old Gen使用到达多少比率时触发; -XX:CMSInitiatingPermOccupancyFraction,设置Perm Gen使用到达多少比率时触发; -XX:+UseCMSInitiatingOccupancyOnly ,禁止hotspot自行触发CMS GC; Case Show!
  • 30. Garbage Collector - Summaryimport java.util.*; public class SummaryCase{ public static void main(String[] args) { List caches=new ArrayList(); 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
  • 31. Garbage Collector – FutureGarbage First (G1) JDK 1.6 update 14 or JDK 7 Few flags need to set -XX:MaxGCPauseMillis=100 -XX:GCPauseIntervalMillis=6000
  • 32. 常见问题 -- OOMjava.lang.OutOfMemoryError: {$reason} GC overhead limit exceeded Java Heap Space Unable to create new native thread PermGen Space request {} bytes for {}. Out of swap space?
  • 33. 常见问题 -- OOMGC overhead limit exceeded Java Heap Space 未处理此类异常会造成线程退出 线程调度慢 系统响应慢或无响应 because gc频繁 Out of Swap Java进程crash
  • 34. 常见问题 -- OOMGC overhead limit exceeded Java Heap Space 存活的对象超过了Heap的大小; Out of Swap 地址空间不够用了 堆外内存(物理内存 + Swap)不够用了
  • 35. 常见问题 -- OOMGC overhead limit exceeded Java Heap Space -XX:+HeapDumpOnOutOfMemoryError jmap –histo pid jmap –dump:file={filename},format=b pid eclipse mat (one big memory machine) btrace
  • 36. 常见问题 -- OOMOut of Swap ps gux google-perftools
  • 37. 常见问题 -- OOMOOM 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
  • 38. 常见问题 -- OOM实际的Cases 现场讲解…
  • 39. 常见问题 -- OOM解决方法 GC overhead limit exceeded Java Heap Space monitor app log & gc log heap dump or jmap –histo|-dump when oom mat analyze heap dump app developer or btrace to find where cause
  • 40. 常见问题 -- OOM解决方法 Out of swap crash log google-perftools then btrace to find where cause
  • 41. 常见问题 -- OOMWrite OOM Friendly Code 慎用ThreadLocal; 限制Collection/StringBuilder等的大小; 限制提交的请求的大小,尤其是批量处理; 限制数据库返回的数据的大小; 避免死循环。
  • 42. 常见问题 – GC频繁内存使用过多造成的GC频繁; 悲观策略造成的GC频繁Case;
  • 43. 回顾ClassLoader TraceClassLoading 解释执行 C1 or C2 逃逸分析 Inline GC New Gen/Eden/Survivor Space/Old Gen/PermGen Serial/Parallel/Concurrent GC OOM