VisualVM jvm gc调优_安装_原理_配置_集成_日志_验证_分析
一 、 VisualVM与eclipse集成、验证
1.1 到官网下载VisualVM包
2. 1 将visualvm_launcher_u1_eclipse_36.zip解压到Eclipse主目录,如图所示:
2 在Eclipse中加入新插件:Help—>install new software 然后add—>local 刚刚解压的visualvm_launcher_u1_eclipse_36目录,如图:ok之后显示下边的界面就代表成功了,直接next安装就行了
3 配置:在window的preferences中进行VisualVM的配置,需要配置它的启动器(jdk、bin目录下面的jvisualvm.exe)还有jdk目录,如图所示,点击apply,ok即可完成安装配置:
4,验证(针对某一代码)
二、针对eclipse 启动jvm 调优
除了常规eclipse内部设置(请参考 http://yuanzhifei89.iteye.com/blog/974082),主要针对jvm调优来加快eclipse启动速度
2.1 本笔记本为例
硬件:
2.2 eclipse未进行精确配置之前的vm 性能情况(eclipse内置大项目,含10多个子项目)
elipse.ini:
-vm
C:/Program Files/Java/jdk1.8.0_31/bin/javaw.exe
-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-
1440.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.200
.v20140116-2212
-product
org.eclipse.epp.package.jee.product
-showsplash
org.eclipse.platform
-vmargs
-Dcom.sun.management.jmxremote
-Dosgi.requiredJavaVersion=1.8
在eclipse.ini文件下增加如下配置:
-server
-Xverify:none
-Xms512m
-Xmx512m
-Xmn192m
-Xss1m
-XX:PermSize=96m
-XX:MaxPermSize=96m
-XX:+UseParallelGC
-XX:+DisableExplicitGC
-XX:+PrintGCDetails
-Xloggc:gc.log
验证:
为什么提高了这么多?
原理分析:
-Xmx512m | 最大总堆内存,一般设置为物理内存的1/4 |
-Xms512m | 初始总堆内存,一般将它设置的和最大堆内存一样大,这样就不需要根据当前堆使用情况而调整堆的大小了 |
-Xmn192m | 年轻代堆内存,sun官方推荐为整个堆的3/8 |
堆内存的组成 | 总堆内存 = 年轻代堆内存 + 年老代堆内存 + 持久代堆内存 |
年轻代堆内存 | 对象刚创建出来时放在这里 |
年老代堆内存 | 对象在被真正会回收之前会先放在这里 |
持久代堆内存 | class文件,元数据等放在这里 |
-XX:PermSize=128m | 持久代堆的初始大小 |
-XX:MaxPermSize=128m | 持久代堆的最大大小,eclipse默认为256m。如果要编译jdk这种,一定要把这个设的很大,因为它的类太多了。 |
2.3 日志分析,配置调优
Java HotSpot(TM) Server VM (25.31-b07) for windows-x86 JRE (1.8.0_31-b13), built on Dec 17 2014 20:43:10 by "java_re" with MS VC++ 10.0 (VS2010) Memory: 4k page, physical 3119408k(1437320k free), swap 6237052k(3591364k free) CommandLine flags: -XX:-BytecodeVerificationLocal -XX:-BytecodeVerificationRemote -XX:+DisableExplicitGC -XX:InitialHeapSize=536870912 -XX:+ManagementServer -XX:MaxHeapSize=536870912 -XX:MaxNewSize=201326592 -XX:NewSize=201326592 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:ThreadStackSize=1024 -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC 5.604: [GC (Metadata GC Threshold) [PSYoungGen: 91471K->20157K(172032K)] 91471K->20169K(499712K), 0.0793352 secs] [Times: user=0.11 sys=0.02, real=0.08 secs] 5.684: [Full GC (Metadata GC Threshold) [PSYoungGen: 20157K->0K(172032K)] [ParOldGen: 12K->19540K(327680K)] 20169K->19540K(499712K), [Metaspace: 15531K->15531K(16768K)], 0.2561745 secs] [Times: user=0.42 sys=0.03, real=0.26 secs] 14.046: [GC (Metadata GC Threshold) [PSYoungGen: 118874K->24563K(172032K)] 138414K->51325K(499712K), 0.1275868 secs] [Times: user=0.20 sys=0.02, real=0.13 secs] 14.174: [Full GC (Metadata GC Threshold) [PSYoungGen: 24563K->0K(172032K)] [ParOldGen: 26761K->41148K(327680K)] 51325K->41148K(499712K), [Metaspace: 25737K->25737K(28032K)], 0.5129513 secs] [Times: user=0.92 sys=0.00, real=0.51 secs] 22.435: [GC (Allocation Failure) [PSYoungGen: 147456K->24561K(172032K)] 188604K->70171K(499712K), 0.1349419 secs] [Times: user=0.14 sys=0.01, real=0.13 secs] 27.247: [GC (Allocation Failure) [PSYoungGen: 172017K->18561K(172032K)] 217627K->64180K(499712K), 0.0859677 secs] [Times: user=0.17 sys=0.00, real=0.09 secs] 29.967: [GC (Metadata GC Threshold) [PSYoungGen: 157939K->21687K(169216K)] 203558K->67314K(496896K), 0.1142016 secs] [Times: user=0.19 sys=0.00, real=0.11 secs] 30.082: [Full GC (Metadata GC Threshold) [PSYoungGen: 21687K->0K(169216K)] [ParOldGen: 45626K->51089K(327680K)] 67314K->51089K(496896K), [Metaspace: 43151K->43151K(46464K)], 1.1417659 secs] [Times: user=1.86 sys=0.02, real=1.14 secs] 34.104: [GC (Allocation Failure) [PSYoungGen: 147456K->7440K(150272K)] 198545K->58529K(477952K), 0.1029235 secs] [Times: user=0.17 sys=0.02, real=0.10 secs] 36.766: [GC (Allocation Failure) [PSYoungGen: 130320K->10040K(133120K)] 181409K->61133K(460800K), 0.1721920 secs] [Times: user=0.14 sys=0.00, real=0.17 secs] 40.052: [GC (GCLocker Initiated GC) [PSYoungGen: 132920K->14518K(160256K)] 188198K->69796K(487936K), 0.0870079 secs] [Times: user=0.16 sys=0.00, real=0.09 secs] 44.047: [GC (Allocation Failure) [PSYoungGen: 137398K->24118K(159232K)] 192691K->79412K(486912K), 0.1270519 secs] [Times: user=0.20 sys=0.00, real=0.13 secs] 47.582: [GC (Allocation Failure) [PSYoungGen: 146998K->26158K(158720K)] 202292K->81455K(486400K), 0.2790460 secs] [Times: user=0.37 sys=0.00, real=0.28 secs] 49.515: [GC (Allocation Failure) [PSYoungGen: 148526K->27808K(150272K)] 203823K->83106K(477952K), 0.5693700 secs] [Times: user=1.12 sys=0.00, real=0.57 secs] 55.447: [GC (Allocation Failure) [PSYoungGen: 150176K->27385K(157440K)] 205474K->82687K(485120K), 0.1323813 secs] [Times: user=0.25 sys=0.00, real=0.13 secs] 812.816: [GC (Allocation Failure) [PSYoungGen: 146681K->27979K(147456K)] 201983K->83284K(475136K), 0.1463265 secs] [Times: user=0.20 sys=0.00, real=0.15 secs] 1471.976: [GC (Allocation Failure) [PSYoungGen: 147275K->27377K(157184K)] 202580K->82682K(484864K), 0.1281856 secs] [Times: user=0.27 sys=0.00, real=0.13 secs]
1、在eclipse的启动过程中,JIT对字节码进行了向机器码的
编译,耗时18s
Class加载耗时44s
Minor GC发生了13次,耗时2.15s
Full GC发生了3次, 耗时1.9s
2、日志做了3次full gc 与 visualvm 上图显示是一致,old gen 老年代耗时1.9s(日志:0.26+0.51+1.14)
2.4 eclipse退出后heap的日志分析
Heap PSYoungGen total 157184K, used 99532K [0x24e00000, 0x30e00000, 0x30e00000) eden space 117760K, 61% used [0x24e00000,0x29476ba0,0x2c100000) from space 39424K, 69% used [0x2e780000,0x3023c550,0x30e00000) to space 39424K, 0% used [0x2c100000,0x2c100000,0x2e780000) ParOldGen total 327680K, used 55305K [0x10e00000, 0x24e00000, 0x24e00000) object space 327680K, 16% used [0x10e00000,0x14402510,0x24e00000) Metaspace used 51057K, capacity 53827K, committed 53888K, reserved 54656K
jvm区域总体分两类,heap区和非heap区。heap区又分:EdenSpace(伊甸园)、Survivor Space(幸存者区)、Tenured Gen(老年代-养老区)。非heap区又分:Code Cache(代码缓存区)、Perm Gen(永久代)、Jvm Stack(java虚拟机栈)、Local Method Statck(本地方法栈)。
HotSpot虚拟机GC算法采用分代收集算法:
1、一个人(对象)出来(new 出来)后会在EdenSpace(伊甸园)无忧无虑的生活,直到GC到来打破了他们平静的生活。GC会逐一问清楚每个对象的情况,有没有钱(此对象的引用)啊,因为GC想赚钱呀,有钱的才可以敲诈嘛。然后富人就会进入Survivor Space(幸存者区),穷人的就直接kill掉。
2、并不是进入Survivor Space(幸存者区)后就保证人身是安全的,但至少可以活段时间。GC会定期(可以自定义)会对这些人进行敲诈,亿万富翁每次都给钱,GC很满意,就让其进入了Genured Gen(养老区)。万元户经不住几次敲诈就没钱了,GC看没有啥价值啦,就直接kill掉了。
3、进入到养老区的人基本就可以保证人身安全啦,但是亿万富豪有的也会挥霍成穷光蛋,只要钱没了,GC还是kill掉。
分区的目的:新生区由于对象产生的比较多并且大都是朝生夕灭的,所以直接采用标记-清理算法。而养老区生命力很强,则采用复制算法,针对不同情况使用不同算法。
非heap区域中Perm Gen中放着类、方法的定义,jvm Stack区域放着方法参数、局域变量等的引用,方法执行顺序按照栈的先入后出方式。
GC工作机制
SUN的jvm内存池被划分为以下几个部分:
Eden Space (heap)
内存最初从这个线程池分配给大部分对象。
Survivor Space (heap)
用于保存在eden space内存池中经过垃圾回收后没有被回收的对象。
Tenured Generation (heap)
用于保持已经在survivor space内存池中存在了一段时间的对象。
Permanent Generation (non-heap)
保存虚拟机自己的静态(reflective)数据,例如类(class)和方法(method)对象。Java虚拟机共享这些类数据。这个区域被分割为只读的和只写的。
Code Cache (non-heap)
HotSpot Java虚拟机包括一个用于编译和保存本地代码(nativecode)的内存,叫做“代码缓存区”(code cache)。
简单来讲,jvm的内存回收过程是这样的:
对象在Eden Space创建,当Eden Space满了的时候,gc就把所有在Eden Space中的对象扫描一次,把所有有效的对象复制到第一个Survivor Space,同时把无效的对象所占用的空间释放。当Eden Space再次变满了的时候,就启动移动程序把Eden Space中有效的对象复制到第二个Survivor Space,同时,也将第一个Survivor Space中的有效对象复制到第二个Survivor Space。如果填充到第二个Survivor Space中的有效对象被第一个Survivor Space或Eden Space中的对象引用,那么这些对象就是长期存在的,此时这些对象将被复制到Permanent Generation。
若垃圾收集器依据这种小幅度的调整收集不能腾出足够的空间,就会运行Full GC,此时jvm gc停止所有在堆中运行的线程并执行清除动作。
2.5 经上论述,我们进行优化
eclipse.ini:
-vm
C:/Program Files/Java/jdk1.8.0_31/bin/javaw.exe
-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.200
.v20140116-2212
-product
org.eclipse.epp.package.jee.product
-showsplash
org.eclipse.platform
-vmargs
-Dcom.sun.management.jmxremote
-Dosgi.requiredJavaVersion=1.8
-server
-Xverify:none
-Xms768m
-Xmx768m
-Xmn288m
-Xss2m
-XX:PermSize=128m
-XX:MaxPermSize=128m
-XX:+UseParallelGC
-XX:+DisableExplicitGC
-XX:+PrintGCDetails
-Xloggc:gc.log
Java HotSpot(TM) Server VM (25.31-b07) for windows-x86 JRE (1.8.0_31-b13), built on Dec 17 2014 20:43:10 by "java_re" with MS VC++ 10.0 (VS2010) Memory: 4k page, physical 3119408k(1201144k free), swap 6237052k(3588912k free) CommandLine flags: -XX:-BytecodeVerificationLocal -XX:-BytecodeVerificationRemote -XX:+DisableExplicitGC -XX:InitialHeapSize=805306368 -XX:+ManagementServer -XX:MaxHeapSize=805306368 -XX:MaxNewSize=301989888 -XX:NewSize=301989888 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:ThreadStackSize=2048 -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC 5.595: [GC (Metadata GC Threshold) [PSYoungGen: 101748K->20182K(258048K)] 101748K->20194K(749568K), 0.0706201 secs] [Times: user=0.09 sys=0.00, real=0.07 secs] 5.666: [Full GC (Metadata GC Threshold) [PSYoungGen: 20182K->0K(258048K)] [ParOldGen: 12K->19574K(491520K)] 20194K->19574K(749568K), [Metaspace: 15539K->15539K(16768K)], 0.2421043 secs] [Times: user=0.38 sys=0.05, real=0.24 secs] 12.416: [GC (Metadata GC Threshold) [PSYoungGen: 143771K->31916K(258048K)] 163345K->51494K(749568K), 0.1186601 secs] [Times: user=0.20 sys=0.02, real=0.12 secs] 12.535: [Full GC (Metadata GC Threshold) [PSYoungGen: 31916K->0K(258048K)] [ParOldGen: 19578K->41244K(491520K)] 51494K->41244K(749568K), [Metaspace: 25787K->25787K(28032K)], 0.5092689 secs] [Times: user=0.89 sys=0.01, real=0.51 secs] 22.767: [GC (Metadata GC Threshold) [PSYoungGen: 167163K->35899K(258048K)] 208408K->77148K(749568K), 0.1167970 secs] [Times: user=0.22 sys=0.00, real=0.12 secs] 22.884: [Full GC (Metadata GC Threshold) [PSYoungGen: 35899K->0K(258048K)] [ParOldGen: 41248K->64287K(491520K)] 77148K->64287K(749568K), [Metaspace: 43036K->43036K(46464K)], 1.0901850 secs] [Times: user=1.69 sys=0.00, real=1.09 secs] 30.941: [GC (Allocation Failure) [PSYoungGen: 221184K->14279K(258048K)] 285471K->78571K(749568K), 0.2243615 secs] [Times: user=0.31 sys=0.00, real=0.22 secs] 34.712: [GC (Allocation Failure) [PSYoungGen: 235463K->18225K(239616K)] 299755K->82521K(731136K), 0.1056951 secs] [Times: user=0.20 sys=0.00, real=0.11 secs] 37.463: [GC (Allocation Failure) [PSYoungGen: 239409K->24716K(255488K)] 303705K->89012K(747008K), 0.1437745 secs] [Times: user=0.20 sys=0.02, real=0.14 secs] 40.641: [GC (Allocation Failure) [PSYoungGen: 238220K->31239K(252928K)] 302516K->95535K(744448K), 0.4823364 secs] [Times: user=0.97 sys=0.00, real=0.48 secs] 45.549: [GC (Allocation Failure) [PSYoungGen: 244743K->33387K(250880K)] 309039K->97687K(742400K), 0.2796351 secs] [Times: user=0.55 sys=0.00, real=0.28 secs] 380.693: [GC (Allocation Failure) [PSYoungGen: 243307K->35404K(245504K)] 307607K->99704K(737024K), 0.1724127 secs] [Times: user=0.31 sys=0.00, real=0.17 secs] Heap PSYoungGen total 245504K, used 108472K [0x2f000000, 0x41000000, 0x41000000) eden space 209920K, 34% used [0x2f000000,0x3375af58,0x3bd00000) from space 35584K, 99% used [0x3bd00000,0x3df933c0,0x3dfc0000) to space 44544K, 0% used [0x3e480000,0x3e480000,0x41000000) ParOldGen total 491520K, used 64299K [0x11000000, 0x2f000000, 0x2f000000) object space 491520K, 13% used [0x11000000,0x14ecaf50,0x2f000000) Metaspace used 50885K, capacity 53620K, committed 53632K, reserved 53632K
与实际的体验相符,速度很快了且较为稳定~