一、你平时工作用过的jvm常用基本配置参数有哪些?
1、回顾堆内存初始大小
jdk1.8之后将最初永久代取消了,由元空间取代。
在jdk1.8中,永久已经被移除,被一个称为元空间的区域取代。元空间的本质和永久代类似。
元空间(java8)与永久代(java7)之间最大的区别在于:
永久代使用的jvm的堆内存,但是java8以后的元空间并不在虚拟机中而是使用本机物理内存
因此,默认情况下,元空间的大小仅受本地内存的限制。类的元数据放入native memory,字符串池和类的静态变量放入到java堆中,这样可以加载多少类的元数据就不再由MaxPermSize控制,而由系统的实际可用空间来控制。
代码案例:
package com.study.jvmgc;
public class HelloGC01 {
public static void main(String[] args) throws Exception{
long totalMemory = Runtime.getRuntime().totalMemory(); // 返回java虚拟机中的内存总量
long maxMemory = Runtime.getRuntime().maxMemory(); // 返回java虚拟机试图使用的最大内存量
System.out.println("TotalMemory(-Xms) = " + totalMemory + " (字节)、" + (totalMemory / (double) 1024 / 1024) + " MB");
System.out.println("MaxMemory(-Xmx) = " + maxMemory + " (字节)、" + (maxMemory / (double) 1024 / 1024) + " MB");
}
}
运行程序,输出:
2、常用基础参数栈内存Xss讲解
(1)-Xms:初始大小内存,默认为物理内存1/64 —— 等价于-XX:InitialHeapSize
(2)-Xmx:最大分配内存,默认为物理内存1/4 —— 等价于-XX:MaxHeapSize
(3)-Xss:设置单个线程的大小,一般默认为512K~102 —— 等价于-XX:ThreadStackSize
代码案例:
package com.study.jvmgc;
public class HelloGC {
public static void main(String[] args) throws Exception{
System.out.println("************HelloGC");
Thread.sleep(Integer.MAX_VALUE);
}
}
运行程序后,执行查看
解决以上问题:
把参数-XX:MetaspaceSize=1204m改成-Xss128K
再次启动运行并执行命令:
原理:如-XX:ThreadStackSize=0时,代表用户系统出场默认值;
查看oracle官网资料:https://docs.oracle.com/javase/8/docs/index.html
在java虚拟机中,栈管运行,堆管存储
由栈空间有128,如图所示:
若无指定配置Vm参数,它的栈空间的值为0,这个问题我们又当如何解释呢?
我们可以根据java8的官网信息去验证:https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html
其次,不管时java9、java10、java11、java12都是默认于平台。
https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-3B1CE181-CD30-4178-9602-230B800D4FAE
https://docs.oracle.com/en/java/javase/12/docs/specs/man/java.html
3、常用基础参数元空间MetaspaceSize
(1)-Xmn:设置年轻代大小
(2)-XX:MetaspaceSize:设置元空间大小
其中,元空间的本质与永久代类似,都是对jvm规范中方法区的实现。不过元空间与永久代之间最大的区别在于: 元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制
查看初始参数
-XX:+PrintCommandLineFlags
运行程序后,如下图,发现会自定义参数打印数据(串行垃圾回收器)
其中:
-XX:+UseSerialGC 串行垃圾回收器
-XX:+UseParallelGC 并行垃圾回收器 ( jdk1.8 默认)
运行的参数值:
//串行垃圾回收器
-XX:InitialHeapSize=132335808
-XX:MaxHeapSize=2117372928
-XX:+PrintCommandLineFlags
-XX:+UseCompressedClassPointers
-XX:+UseCompressedOops
-XX:-UseLargePagesIndividualAllocation
-XX:+UseParallelGC
另一种配置参数:并行垃圾回收器
-Xms128m -Xmx4096m -Xss1024k -XX:MetaspaceSize=512m -XX:+PrintCommandLineFlags
-XX:+PrintGCDetails -XX:+UseSerialGC
运行程序后,如下图:
运行的参数值:
//并行垃圾回收器 ( jdk1.8 默认)
-XX:InitialHeapSize=134217728
-XX:MaxHeapSize=4294967296
-XX:MetaspaceSize=536870912
-XX:+PrintCommandLineFlags
-XX:+PrintGCDetails
-XX:ThreadStackSize=1024
-XX:+UseCompressedClassPointers
-XX:+UseCompressedOops
-XX:-UseLargePagesIndividualAllocation
-XX:+UseSerialGC
4、常用基础参数PrintCDetails回收前后对比讲解
(1)查看垃圾回收细节情况信息
-XX:+PrintGCDetails
启动程序:垃圾回收细节情况信息
若在生产环境中,出现另类的情况,比如说把垃圾回收内存爆出现象,配置参数
-Xms10m -Xmx10m -XX:+PrintGCDetails
//代码演示:
package com.study.jvmgc;
public class HelloGC {
public static void main(String[] args) throws Exception{
System.out.println("************HelloGC");
byte[]byteArray=new byte[50*1024*1024];
}
}
启动程序,控制台打印输出:
oom挂了
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.study.jvmgc.HelloGC.main(HelloGC.java:7)
一般了说,GC在新生区
而Full GC在年老区
5、常用基础参数SurvivorRation讲解
设置新生代中eden和S0/S1空间的比例默认:
-XX:SurvivorRation=8, Eden:S0:S1=8:1:1
假如:
-XX:SurvivorRation=4,Eden:S0:S1=4:1:1
SurvivorRation值就是设置eden区的比例占多少,S0/S1相同
代码案例演示:
配置jvm参数:
//配置串行垃圾回收
-XX:+PrintGCDetails -XX:+UseSerialGC -Xms10m -Xmx10m
启动程序,输出:默认值,参数没有做更改
若想要更改默认参数,在idea修改jvm的配置参数即可:
-XX:+PrintGCDetails -XX:+UseSerialGC -Xms10m -Xmx10m -XX:SurvivorRation=8 //默认值
打印输出:
若想更改别的参数,比如设置为4
-XX:+PrintGCDetails -XX:+UseSerialGC -Xms10m -Xmx10m -XX:SurvivorRation=4 //4倍
打印输出:
6、常用基础参数NewRation
配置年轻代与老年代在堆结构的占比默认,-XX:NewRation=2,新生代占1,老年代占2,年轻代占整个堆的1/3。
假如:-XX:NewRation=4,新生代占1,老年代占4,年轻代占整个堆的1/5。
NewRation值就是设置老年代的占比,剩下的1给新生代
代码案例演示:
配置jvm参数,串行垃圾回收信息
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+UseSerialGC
打印输出:
若想要更改默认参数,在idea修改jvm的配置参数即可,修改后新生代与老年代都会发生变化
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:NewRatio=4
打印输出:
若想要更改参数2
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:NewRatio=2
打印输出:
7、常用基础参数MaxTenuringThreshold
若我们在idea不配置虚拟机参数
代码案例:
package com.study.jvmgc;
public class HelloGC {
public static void main(String[] args) throws Exception{
System.out.println("************HelloGC");
Thread.sleep(Integer.MAX_VALUE);
}
}
启动程序,打印输出,查看
E:interview2020-master>jinfo -flag MaxTenuringThreshold 5368
注意:在java8默认参数的范围0~15,调优参数系统已经配置好了,若超过15系统不许,会出现错误。
如设置参数为20
-XX:MaxTenuringThreshold=20
运行报错信息,如图所示:java8限制了
不超过15即可,如设置参数为12
-XX:MaxTenuringThreshold=12