常用jvm参数跑配置"/>
第三课:常用jvm参数跑配置
1.trace跟踪参数
大多是对gc的方式进行跟踪。而能够显示gc信息的,要么是开启gc开关,要么是使用printGC方法。
而一个GC的跟踪日志格式是:
-[GC 4790 -> 374(15872K),0.0001606SECS]gc前 -> gc后(一共) , 所花时间
这些信息比较简单,但是如果想知道详细信息可以使用如下方法:
1…printGCDetails 详细信息
2…PrintGCTimaStamps 时间戳
详细信息下:
[GC[DefNew:4416 -> 0(4928k),0.0001897 secs]4790k(15872k),0.0002232 secs][Times:user = 0.00 sys = 0.00,real = 0.00secs] XX:+PrintGCDetails的输出–Heap 低边界 , 当前边界 , 最高边界(起止位置,当前申请到的位置,最高能申请到的位置)(0x28d80000 - 0x27e80000)/1024/1024 = 15–def new generation total 13824K, used 11223K [0x27e80000, 0x28d80000, 0x28d80000)–eden space 12288K, 91% used [0x27e80000, 0x28975f20, 0x28a80000)【新生代,对象产生的地方】–from space 1536K, 0% used [0x28a80000, 0x28a80000, 0x28c00000)–to space 1536K, 0% used [0x28c00000, 0x28c00000, 0x28d80000)–tenured generation total 5120K, used 0K [0x28d80000, 0x29280000, 0x34680000)【老年代】–the space 5120K, 0% used [0x28d80000, 0x28d80000, 0x28d80200, 0x29280000)–compacting perm gen total 12288K, used 142K [0x34680000, 0x35280000, 0x38680000)【永久区,方法区,这个使用的比较少,因为在jdk5以后,在永久区就有一个类的共享,一些基本的java的类会加载到一个共享的区间里面,供所有的虚拟机使用】–the space 12288K, 1% used [0x34680000, 0x346a3a90, 0x346a3c00, 0x35280000)–ro space 10240K, 44% used [0x38680000, 0x38af73f0, 0x38af7400, 0x39080000)【共享区的大小,readonly 只读】–rw space 12288K, 52% used [0x39080000, 0x396cdd28, 0x396cde00, 0x3【共享区的大小,readwrite 读写】
3…重定向gc日志:-Xloggc:log/gc.log
4…printHeapAtGC:
Heap before GC invocations=0 (full 0):gc前:def new generation total 3072K,used 2752K [0x33c80000, 0x33fd0000, 0x33fd0000)eden space 2752K, 100% used [0x33c80000, 0x33f30000, 0x33f30000)from space 320K, 0% used [0x33f30000, 0x33f30000, 0x33f80000)to space 320K, 0% used [0x33f80000, 0x33f80000, 0x33fd0000)tenured generation total 6848K, used 0K [0x33fd0000, 0x34680000, 0x34680000)the space 6848K, 0% used [0x33fd0000, 0x33fd0000, 0x33fd0200, 0x34680000)compacting perm gen total 12288K, used 143K [0x34680000, 0x35280000, 0x38680000)the space 12288K, 1% used [0x34680000, 0x346a3c58, 0x346a3e00, 0x35280000)ro space 10240K, 44% used [0x38680000, 0x38af73f0, 0x38af7400, 0x39080000)rw space 12288K, 52% used [0x39080000, 0x396cdd28, 0x396cde00, 0x39c80000)[GC[DefNew: 2752K->320K(3072K), 0.0014296 secs] 2752K->377K(9920K), 0.0014604 secs][Times: user=0.00 sys=0.00, real=0.00 secs] gc后:Heap after GC invocations=1 (full 0):def new generation total 3072K, used 320K [0x33c80000, 0x33fd0000, 0x33fd0000)eden space 2752K, 0% used [0x33c80000, 0x33c80000, 0x33f30000)from space 320K, 100% used [0x33f80000, 0x33fd0000, 0x33fd0000)to space 320K, 0% used [0x33f30000, 0x33f30000, 0x33f80000) tenured generation total 6848K, used 57K [0x33fd0000, 0x34680000, 0x34680000)the space 6848K, 0% used [0x33fd0000, 0x33fde458, 0x33fde600, 0x34680000)compacting perm gen total 12288K, used 143K [0x34680000, 0x35280000, 0x38680000)the space 12288K, 1% used [0x34680000, 0x346a3c58, 0x346a3e00, 0x35280000)ro space 10240K, 44% used [0x38680000, 0x38af73f0, 0x38af7400, 0x39080000)rw space 12288K, 52% used [0x39080000, 0x396cdd28, 0x396cde00, 0x39c80000)}
5…TraceClssLoading 监控类的加载
eg: •[Loaded java.lang.Object from shared objects file](超类)•[Loaded java.io.Serializable from shared objects file]•[Loaded java.lang.Comparable from shared objects file]•[Loaded java.lang.CharSequence from shared objects file]•[Loaded java.lang.String from shared objects file]•[Loaded java.lang.reflect.GenericDeclaration from shared objects file]•[Loaded java.lang.reflect.Type from shared objects f
6…PrintClassHistogram
ps:当你输入这个方法的时候,是没有任何信息打印出来的。你要是想要显示这个类的的直方图的信息,需要摁下crtl+break键位
num #instances #bytes class name----------------------------------------------1: 890617 470266000 [B【byte】2: 890643 21375432 java.util.HashMap$Node3: 890608 14249728 java.lang.Long4: 13 8389712 [Ljava.util.HashMap$Node;5: 2062 371680 [C【char】6: 463 41904 java.lang.Class序号 实例数量 总大小 类型
2.堆的参数设置与分配
1…-Xmx -Xma
-Xmx20m -Xma5m(最大20m,最小5m)制定最大堆和最小堆 max Runtime.getRuntime().maxMemory()/1024/1024 (M)free Runtime.getRuntime().freeMemory()/1024/1024 (M) total Runtime.getRuntime().totalMemory()/1024/1024 (M)result:Xmx = 19.375Mfree mem = 4.346578997654768M(剩余可用)total mem = 4.875M当你规定了最小堆,java会尽可能的在最小堆中运行,所以这里的total是:4.875M。如果这个最小的空间,不够分配的,就会自动扩容
2…-Xmn 设置新生代大小
(新生代是由eden和幸存区组成)
-XX :NewRatio(一个新生代和老年代的比例)-新生代(eden + 2*s)和老年代(不包含永久区)的比值——比如4表示 新生代:老年代 = 1:4 ,即年轻代占堆的1/5-SurvivorRatio 幸存-设置两个Suivior(from ··· to)区和eden的比值-8表示 两个Survivor:eden = 2:8 ,即一个Survivor占年轻代的1/10
example:
public static void mian(String args[]){byte[] b = null;for (int i =0 ; i<10 ;i++){b = new byte[1*1024*1024];}}
按照上面的例子,配置几个参数.
一丶参数配置是 :-Xmx20m -Xms20m -Xmn1m(eden+survibvor*2) -xx:+printGCDetails
【因为新生代太小,所以直接放在老年代。】def new generation total 960k, used 643K [0x33060000, 0x33160000, 0x33160000)eden space 896K, 71% used [0x33060000, 0x33100cb0, 0x33140000)from space 64K, 0% used [0x33f80000, 0x33fd0000, 0x33fd0000)to space 64K, 0% used [0x33f30000, 0x33f30000, 0x33f80000) tenured generation total 19456K, used 10240K [0x33160000, 0x34460000, 0x34460000)the space 19456K, 52% used [0x33160000, 0x33b600a0, 0x33b60200, 0x34460000)【占到老年代分配的%52的比例】compacting perm gen total 12288K, used 147K [0x34460000, 0x35060000, 0x3846000)the space 12288K, 1% used [0x34460000, 0x34484ef8, 0x34485000, 0x35060000)ro space 10240K, 44% used [0x38460000, 0x388d73f0, 0x388d7400, 0x38e60000)rw space 12288K, 52% used [0x38e60000, 0x396add28, 0x396ade00, 0x39a60000)1.没有发生gc2.全部分配到了老年代
二丶参数配置是 :-Xmx20m -Xms20m -Xmn15m(eden+survibvor*2) -xx:+printGCDetails
Heapdef new generation total 13824k, used 11224K [0x33060000, 0x33160000, 0x33160000)eden space 12288K, 91% used [0x33060000, 0x33100cb0, 0x33140000)【12M】from space 1536K, 0% used [0x33f80000, 0x33fd0000, 0x33fd0000)【1.5M】to space 1536K, 0% used [0x33f30000, 0x33f30000, 0x33f80000) 【1.5M】 tenured generation total 5120K, used 0K [0x33160000, 0x34460000, 0x34460000)the space 5120K, 0% used [0x33160000, 0x33b600a0, 0x33b60200, 0x34460000)【占到老年代分配的%52的比例】compacting perm gen total 12288K, used 147K [0x34460000, 0x35060000, 0x3846000)the space 12288K, 1% used [0x34460000, 0x34484ef8, 0x34485000, 0x35060000)ro space 10240K, 44% used [0x38460000, 0x388d73f0, 0x388d7400, 0x38e60000)rw space 12288K, 52% used [0x38e60000, 0x396add28, 0x396ade00, 0x39a60000)1.没有发生gc2.全部分配到了eden3.没有用到老年代
三丶参数配置是 :-Xmx20m -Xms20m -Xmn7m(eden+survibvor*2) -xx:+printGCDetails
[GC[DefNew:4770 -> 460(6464k),0.00014563 secs] 4770k -> 1484k(19776k),0.0015033 secs][Times;user = 0.00 sys = 0.00,real = o.oo secs][GC[DefNew:5760 -> 0k(6464k),0.00013408 secs] 6784k -> 2507k(19776k),0.0013772 secs][Times;user = 0.00 sys = 0.00,real = o.oo secs]Heapdef new generation total 6464, used 1139K [0x33060000, 0x33160000, 0x33160000)eden space 5760K, 19% used [0x33060000, 0x33100cb0, 0x33140000)from space 704K, 0% used [0x33f80000, 0x33fd0000, 0x33fd0000)to space 704K, 0% used [0x33f30000, 0x33f30000, 0x33f80000) tenured generation total 13312K, used 2507K [0x33160000, 0x34460000, 0x34460000)the space 13312K, 18% used [0x33160000, 0x33b600a0, 0x33b60200, 0x34460000)compacting perm gen total 12288K, used 147K [0x34460000, 0x35060000, 0x3846000)the space 12288K, 1% used [0x34460000, 0x34484ef8, 0x34485000, 0x35060000)ro space 10240K, 44% used [0x38460000, 0x388d73f0, 0x388d7400, 0x38e60000)rw space 12288K, 52% used [0x38e60000, 0x396add28, 0x396ade00, 0x39a60000)1.两次gc,第一次回收了大约3M多的内存,第二次大约回收了3M多的内存。总共还剩下大约3M多,也就是1484+2507(k)2.s0,s1太小了,需要老年代担保
四丶参数配置是 :-Xmx20m -Xms20m -Xmn7m(eden+survibvor*2) -xx:SurvivorRatio = 2 -xx:+printGCDetails
[GC[DefNew:2727 -> 1484k(5376k),0.00014563 secs] 4770k -> 1484k(19776k),0.0015033 secs][Times;user = 0.00 sys = 0.00,real = o.oo secs][GC[DefNew:4672 -> 1024k(5376k),0.00014563 secs] 4770k -> 1484k(19776k),0.0015033 secs][Times;user = 0.00 sys = 0.00,real = o.oo secs][GC[DefNew:4125 -> 1024k(5376k),0.00013408 secs] 6784k -> 2507k(19776k),0.0013772 secs][Times;user = 0.00 sys = 0.00,real = o.oo secs]Heapdef new generation total 5376k, used 3163K [0x33060000, 0x33160000, 0x33160000)eden space 3584K, 59% used [0x33060000, 0x33100cb0, 0x33140000)from space 1792K, 59% used [0x33f80000, 0x33fd0000, 0x33fd0000)to space 1792K, 0% used [0x33f30000, 0x33f30000, 0x33f80000) tenured generation total 13312K, used 459k [0x33160000, 0x34460000, 0x34460000)【459k主要是系统级别的内容】the space 13312K, 3% used [0x33160000, 0x33b600a0, 0x33b60200, 0x34460000)compacting perm gen total 12288K, used 147K [0x34460000, 0x35060000, 0x3846000)the space 12288K, 1% used [0x34460000, 0x34484ef8, 0x34485000, 0x35060000)ro space 10240K, 44% used [0x38460000, 0x388d73f0, 0x388d7400, 0x38e60000)rw space 12288K, 52% used [0x38e60000, 0x396add28, 0x396ade00, 0x39a60000)1.进行了三次gc2.s0,s1增大原来的survivor变大了,因为原来的幸存代很小,没有办法正常使用。现在,幸存代可以正常使用了,就可以进行处理了,就不会用到老年代了
五丶-Xmx20m -Xms20m -xx:NewRation:1 -xx:SurvivorRatio = 2 -xx:+printGCDetails
[GC[DefNew:4671 -> 1484k(7680k),0.0017702 secs] 4770k -> 1484k(19776k),0.0018096 secs][Times;user = 0.00 sys = 0.00,real = o.oo secs][GC[DefNew:5368 -> 1024k(7680k),0.0013553 secs] 5638k -> 1484k(19776k),0.0013848 secs][Times;user = 0.00 sys = 0.00,real = o.oo secs]Heapdef new generation total 7680k, used 3315K [0x33060000, 0x33160000, 0x33160000)eden space 5120K, 44% used [0x33060000, 0x33100cb0, 0x33140000)from space 2560K, 40% used [0x33f80000, 0x33fd0000, 0x33fd0000)to space 2560K, 0% used [0x33f30000, 0x33f30000, 0x33f80000) tenured generation total 10240K, used 460k [0x33160000, 0x34460000, 0x34460000)the space 13312K, 4% used [0x33160000, 0x33b600a0, 0x33b60200, 0x34460000)compacting perm gen total 12288K, used 147K [0x34460000, 0x35060000, 0x3846000)the space 12288K, 1% used [0x34460000, 0x34484ef8, 0x34485000, 0x35060000)ro space 10240K, 44% used [0x38460000, 0x388d73f0, 0x388d7400, 0x38e60000)rw space 12288K, 52% used [0x38e60000, 0x396add28, 0x396ade00, 0x39a60000)(pay attention to: gc越多,对堆系统是越不好的。)
六丶-Xmx20m -Xms20m -xx:NewRation:1 -xx:SurvivorRatio = 3 -xx:+printGCDetails(一个幸存区占和eden的比值是1:3)一个幸存区占年轻代的1/5
[GC[DefNew:5858 -> 1484k(8192k),0.0019208 secs] 5858k -> 1484k(19776k),0.0019698 secs][Times;user = 0.00 sys = 0.00,real = o.oo secs]Heapdef new generation total 8192k, used 6919K [0x33060000, 0x33160000, 0x33160000)eden space 6144K, 88% used [0x33060000, 0x33100cb0, 0x33140000)from space 2048K, 72% used [0x33f80000, 0x33fd0000, 0x33fd0000)to space 2048K, 0% used [0x33f30000, 0x33f30000, 0x33f80000) tenured generation total 10240K, used 0k [0x33160000, 0x34460000, 0x34460000)the space 10240K, 0% used [0x33160000, 0x33b600a0, 0x33b60200, 0x34460000)compacting perm gen total 12288K, used 147K [0x34460000, 0x35060000, 0x3846000)the space 12288K, 1% used [0x34460000, 0x34484ef8, 0x34485000, 0x35060000)ro space 10240K, 44% used [0x38460000, 0x388d73f0, 0x388d7400, 0x38e60000)rw space 12288K, 52% used [0x38e60000, 0x396add28, 0x396ade00, 0x39a60000)
3…堆的其他的参数:
1.-xx:+HeapDumpOnOutPutMemoryError-oom时导出堆到文件在outofmemory时做一个堆的转存。当系统发生在outofmemory的时候,系统是运行不稳定的,有可能会宕掉。如果要排查问题,第一在开发环境当中要重现,但是比较困难,运行时间也会比较长。另一种方法是,当他宕掉的时候,就把信息转存出来,推测宕机之前到底发生可什么事情。2.-xx:+HeapDumpPath 放到那里去
eg:
-Xmx20m -Xms5m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/a.dumpVector v=new Vector();for(int i=0;i<25;i++)v.add(new byte[1*1024*1024]);
一共就20m空间,方法分配了25m肯定多。-xx:+HeapDumpOnOutPutMemoryError那怎么办呢? -在OOM时,执行一个脚本–"-XX:OnOutOfMemoryError=D:/tools/jdk1.7_40/bin/printstack.bat %p“ <---------程序D:/tools/jdk1.7_40/bin/jstack -F %1 > D:/a.txt–当程序OOM时,在D:/a.txt中将 会生成线程的dump–可以在OOM时,发送邮件,甚至 是重启 (这个脚本可以随意指定的,可以使发送邮件,报警,重启等等)
4…永久区的参数分配
-XX:PermSize -XX:MaxPermSize–设置永久区的初始空间和最大空间–他们表示,一个系统可以容纳多少个类型
eg:
使用CGLIB等库的时候,可能会产生大量的类,这些类,有可能撑爆永久区导致OOM
for(int i=0;i<100000;i++){CglibBean bean = new ; CglibBean("geym.jvm.ch3.perm.bean"+i,new HashMap()); //不断产生新的类}
新生代占了2% ,老年代占了20%,永久代占据99% 堆空间没有用完,也可能发生oom。因为正如上面例子所示,可能是永久代溢出了,导致了oom。
3.栈的大小分布
-Xss–通常只 有几百K–决定了函数调用的深度–每个线程都有独立的栈空间–局部变量、参数 分配在栈上(每一个方法调用时,都会启用一个栈,而把这些栈加到一起的时候,就是整个存储空间,如果想多跑一些线程的话,是减少栈的大小,而不是增大。)
private static int count=0;public static void recursion(long a,long b,long c){long e=1,f=2,g=3,h=4,i=5,k=6,q=7,x=8,y=9,z=10;count++;recursion(a,b,c);}public static void main(String args[]){try{recursion(0L,0L,0L);}catch(Throwable e){System.out.println("deep of calling = "+count);e.printStackTrace();}}}
递归调用-Xss 分配en128 栈空间Kdeep of calling = 701 调用了701次java.lang.StackOverflowError 这个错误代表了调用的层次太深了-Xss分配256 占空间Kdeep of calling = 1817java.lang.StackOverflowError或者在栈里面的局部变量表,一个是参数,另一个就是函数当中的局部变量。如果能减少局部变量的数量,也能使得栈多调用几次。
这里还有另两个问题:
1.我应该把-xmx -xma配置在一个什么样子的比例,才能使得系统最优化
answer:-Xmx和-Xms一般都是设置相等的,避免在生产环境由于heap内存扩大或缩小导致应用停顿,也避免每次垃圾回收完成后JVM重新分配内存。当然如果生产系统上线前有一段预热时间的话,也可以不设置相等。
2.在开发环境中,用到的jre和jdk特别大。但是我要打包给用户交付的时候不能这么大的都交付给用户,那我应该怎么给jre瘦身呢?
answer:jre 精简就是bin和lib的精简。自己看吧。懒得写了。
精简jre
更多推荐
第三课:常用jvm参数跑配置
发布评论