常用JVM配置参数
常用JVM配置参数主要有Trace跟踪参数、堆的分配参数、栈的分配参数
一、Trace跟踪参数 |
跟踪参数用于跟踪监控JVM,对于开发人员来讲用于JVM调优以及故障排查的
1、打印GC的简要信息
-verbose:gc
-XX:+PrintGC
这两个配置参数效果是一样的,都是在发生GC时打印出简要的信息,例如执行代码
public static void main(String[] args) { byte[] bytes=null; for (int i = 0; i < 100; i++) { bytes=new byte[1*1024*1024*2]; } }
这个程序连续创建了100个2M的数组对象,使用-XX:+PrintGC或-verbose:gc参数执行该程序,即可查看到GC的情况
我们可以看到程序执行了2次GC(minor GC),这两次都是新生代的GC
64645K表示回收前对象占用空间 ,2960K表示回收后对象占用空间,251392K表示还有多少空间可用,0.0019017 secs表示这次垃圾回收花的时间
2、打印GC的详细信息以及堆使用详细信息
--打印GC的详细信息 -XX:+PrintGCDetails --打印GC发生的时间戳 -XX:+PrintGCTimeStamps
使用-XX:+PrintGCDetails参数,查看控制台打印结果:
通过打印GC详细信息可以得出以下结论
(1)Heap(堆)主要分为三大块:堆分为(PSYoungGen)新生代,(ParOldGen)老年代,(Metaspace)元空间
注意这里没有永久区了,永久区在java8已经被移除,原来放在永久区的常量,字符串静态变量都移到了元空间,并使用本地内存
(2)(PSYoungGen)新生代又分为:伊甸区(eden)和幸存区(from和to)
思考:上面的total总的为141824K,它不是应该eden+from+to=total?这是因为新生代的垃圾回收算法采用复制算法,简单来说就是在from和to之间来回复制(复制过程中再把不可达的对象回收掉)
所以必须保证其中一个区是空的,这样才能有预留空间存放复制过来的数据,所以的新生代的总大小其实等于eden+from或to=131072K+10752K=141824K
思考:不同对象一般放在哪个区呢?
(1)新生代主要存放的是那些很快就被GC回收掉的或者不是特别大的对象
(2)老年代则是存放那些程序中经历了好几次回收仍然还活着或者特别大的对象
(3)元空间在这里都是存放一些用于存储类的信息,常量池,方法数据,方法代码等,这个区中的东西比老年代和新生代更不容易回收
3、使用外部文件记录GC的日志
-Xloggc:(指定自己的目录)E:/gc/gc.log
运行程序的时候会有gc.log记录日志文件
二、堆的分配参数 |
1、-Xmx -Xms:指定最大堆和最小堆
我的idea64.exe.vmoptions的配置
-Xms256m
-Xmx1024m
然后我们在程序中运行如下代码:
System.out.println("Xmx="+Runtime.getRuntime().maxMemory()/1024.0/1024+"M"); //系统最大空间 System.out.println("free mem="+Runtime.getRuntime().freeMemory()/1024.0/1024+"M");//系统的空闲空间 System.out.println("total mem="+Runtime.getRuntime().totalMemory()/1024.0/1024+"M");//当前可用的总空间
运行结果:
2、-Xmn、-XX:NewRatio、-XX:SurvivorRatio
-Xmn
设置新生代大小
-XX:NewRatio
新生代(eden+2*s)和老年代(不包括元空间)的比值
例如:4,表示新生代:老年代=1:4 ,即新生代占整个堆的1/5
-XX:SurvivorRatio(幸存区)
设置两个Survivor区和eden的比值
例如:8,表示两个Survivor:eden=2:8,即一个Survivor占年轻代的1/10
举例:
-Xmx20m -Xms20m -XX:NewRatio=1 -XX:SurvivorRatio=3
代表最大最小堆内存都是20m,新生代:老年代1:1,两个Survivor区和eden的比值是2:3
3、-XX:PermSize -XX:MaxPermSize
--设置元数据区的初始空间和最大空间
有关优化总结:
(1)官方推荐新生代占堆的3/8
(2)幸存区占新生代的1/10
三、栈大小分配 |
1、-Xss
通常只有几百K
决定了函数调用的深度
每个线程都有独立的栈空间(栈幁)
局部变量、参数分配在栈上
参考:JVM虚拟机详解