Idea编译器设置虚拟机参数及运行方法和通用参数详细说明
1。设置参数

使用IDEA编译器时,您可以使用以下运行方法来设置虚拟机的参数:
输入VM选项:-XX:+PRINTGCTIMESTAMPS -XX:+PRONTGCDETAILS
2。在控制台上运行并打印以下内容:
3。一般参数描述
-xx:+printGC打印GC的摘要信息
-xx:+printgcdetails可以打印GC详细信息
-xx:+PrintheapatGC打印每个CG之后的堆栈信息
-xx:+printgctimestamps -xx:+printgcdetails在GC发生时打印时间戳
-xx:+traceClassloading监测类的加载
-xx:+heapDumponOutofMemoryError允许虚拟机在发生内存溢出时将当前内存堆转储快照转换为分析。
-xx:+printgctimestamps -xx:+printgcdetails -xloggc:d:\ gc.log输出gc文件
-XMS编号M -XMX数字M指定最小和最大堆
-XMN数字M设置新一代的大小
-xx:permsize -xx:MaxPermsize设置了永久区域,以设置永久区域的初始空间和最大空间。它们表明系统可以容纳多少种类型。
-XSS堆栈尺寸分配
-xx:新一代与旧一代之间的newratiothe比率,例如-xx:newratio = 2,新一代占整个堆积空间的1/3,旧一代占据2/3
-xx:新一代伊甸园与幸存者的生存比率。默认值为8。也就是说,伊甸园占据了新一代空间的8/10,另外两个幸存者占据了1/10。
注意:从JDK 1.8开始,内置的Hostspot虚拟机已取消了先前的永久区域,并添加了一个新的Metaspace区域。从功能的角度来看,Metaspace可以被认为类似于永久区域。它的主要功能是存储元数据。 ,但实际机制是完全不同的。
要限制METASPACE,请使用参数-XX:METASPACESIZE = 64M -XX:MAXMETASPACESIZE = 128M
完整的GC
完整的GC是新一代,旧一代和持续一代的统一回收。由于它正在回收整个空间,因此相对较慢。全GC的数量应在系统中最小化。
全GC将在以下情况下发生:
旧一代的空间不足。持续一代的空间不足。 CMS GC期间发生晋升失败,并发模式失败。统计数据表明,在小型GC期间晋升为旧一代的新一代的平均规模小于旧一代的剩余空间。直接致电System.gc。您可以使用DisableSexpliticgc进行此操作。当禁止RMI调用时,默认情况下将每分钟执行System.GC。您可以通过-dsun.rmi.dgc.server.gcinterval = 3600000设置较大的间隔。
例如:tomcat打印GC日志,在Catinlin.sh的顶部添加
JAVA_OPTS="-XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/lnmp/tomcat8/gc.$$.log"
例如:Springboot Project开始打印GC
java -jar -Dloader.path=$workhome/conf -Xms1526m -Xmx1526m -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:$workhome/log/gc.log -Datlas.home=$workhome $workhome/web-1.0.0-SNAPSHOT.jar --spring.config.location=$workhome/conf/application.yml > $workhome/log/web.log 2>&1 &
打印信息说明:
4。例子
示例1
设置JVM参数如下:
-Xms5m -Xmx20m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags
public class Test01 {
public static void main(String[] args) {
//-Xms5m -Xmx20m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags
//查看GC信息
//maxMemory()这个方法返回的是java虚拟机(这个进程)能构从操作系统那里挖到的最大的内存
System.out.println("max memory:" + Runtime.getRuntime().maxMemory());
//
System.out.println("free memory:" + Runtime.getRuntime().freeMemory());
//totalMemory 返回的是java虚拟机现在已经从操作系统那里挖过来的内存大小,也就是java虚拟机这个进程当时所占用的所有内存。
System.out.println("total memory:" + Runtime.getRuntime().totalMemory());
byte[] b1 = new byte[1*1024*1024];
System.out.println("分配了1M");
System.out.println("max memory:" + Runtime.getRuntime().maxMemory());
System.out.println("free memory:" + Runtime.getRuntime().freeMemory());
System.out.println("total memory:" + Runtime.getRuntime().totalMemory());
byte[] b2 = new byte[4*1024*1024];
System.out.println("分配了4M");
System.out.println("max memory:" + Runtime.getRuntime().maxMemory());
System.out.println("free memory:" + Runtime.getRuntime().freeMemory());
System.out.println("total memory:" + Runtime.getRuntime().totalMemory());
}
}
示例2
设置JVM参数如下:
//第一次配置
//-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
//第二次配置
//-Xms20m -Xmx20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
//第三次配置
//-XX:NewRatio=老年代/新生代
//-Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
public class Test02 {
public static void main(String[] args) {
//第一次配置
//-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
//第二次配置
//-Xms20m -Xmx20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
//第三次配置
//-XX:NewRatio=老年代/新生代
//-Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
byte[] b = null;
//连续向系统申请10MB空间
for(int i = 0 ; i <20; i ++){
b = new byte[1*1024*1024];
}
}
}
示例三
设置JVM参数如下
-Xms1m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/Test03.dump
如何打开转储:双击打开jvisualvm.exe,单击文件 - >加载,在文件类型列中选择堆,选择要分析的转储文件,然后将其打开。
import java.util.Vector;
public class Test03 {
public static void main(String[] args) {
//-Xms1m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/Test03.dump
//堆内存溢出
Vector v = new Vector();
for(int i=0; i < 5; i ++){
v.add(new Byte[1*1024*1024]);
}
}
}
查看转储结果如下:
示例4
1 /**
2 -Xms60m
3 -Xmx60m
4 -Xmn20m
5 -XX:NewRatio=2 ( 若 Xms = Xmx, 并且设定了 Xmn, 那么该项配置就不需要配置了 )
6 -XX:SurvivorRatio=8
7 -XX:PermSize=30m
8 -XX:MaxPermSize=30m
9 -XX:+PrintGCDetails
10 */
11 public static void main(String[] args) {
12 new Test().doTest();
13 }
14
15 public void doTest(){
16 Integer M = new Integer(1024 * 1024 * 1); //单位, 兆(M)
17 byte[] bytes = new byte[1 * M]; //申请 1M 大小的内存空间
18 bytes = null; //断开引用链
19 System.gc(); //通知 GC 收集垃圾
20 System.out.println();
21 bytes = new byte[1 * M]; //重新申请 1M 大小的内存空间
22 bytes = new byte[1 * M]; //再次申请 1M 大小的内存空间
23 System.gc();
24 System.out.println();
25 }
根据上述代码中注释的信息设置与JVM相关的参数,并执行程序。以下是执行后控制台打印的结果:
[ GC [ PSYoungGen: 1351K -> 288K (18432K) ] 1351K -> 288K (59392K), 0.0012389 secs ] [ Times: user=0.00 sys=0.00, real=0.00 secs ]
[ Full GC (System) [ PSYoungGen: 288K -> 0K (18432K) ] [ PSOldGen: 0K -> 160K (40960K) ] 288K -> 160K (59392K) [ PSPermGen: 2942K -> 2942K (30720K) ], 0.0057649 secs ] [ Times: user=0.00 sys=0.00, real=0.01 secs ]
[ GC [ PSYoungGen: 2703K -> 1056K (18432K) ] 2863K -> 1216K(59392K), 0.0008206 secs ] [ Times: user=0.00 sys=0.00, real=0.00 secs ]
[ Full GC (System) [ PSYoungGen: 1056K -> 0K (18432K) ] [ PSOldGen: 160K -> 1184K (40960K) ] 1216K -> 1184K (59392K) [ PSPermGen: 2951K -> 2951K (30720K) ], 0.0052445 secs ] [ Times: user=0.02 sys=0.00, real=0.01 secs ]
Heap
PSYoungGen total 18432K, used 327K [0x00000000fec00000, 0x0000000100000000, 0x0000000100000000)
eden space 16384K, 2% used [0x00000000fec00000,0x00000000fec51f58,0x00000000ffc00000)
from space 2048K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x0000000100000000)
to space 2048K, 0% used [0x00000000ffc00000,0x00000000ffc00000,0x00000000ffe00000)
PSOldGen total 40960K, used 1184K [0x00000000fc400000, 0x00000000fec00000, 0x00000000fec00000)
object space 40960K, 2% used [0x00000000fc400000,0x00000000fc5281f8,0x00000000fec00000)
PSPermGen total 30720K, used 2959K [0x00000000fa600000, 0x00000000fc400000, 0x00000000fc400000)
object space 30720K, 9% used [0x00000000fa600000,0x00000000fa8e3ce0,0x00000000fc400000)
从打印结果可以看出,堆中新一代的记忆空间为18432k(约18m),伊甸园的内存空间为16384k(约16m),从 /到幸存者的存储空间为2048k(约2m)。
此处配置的XMN是20m,这意味着新一代的内存空间指定为20m。但是,从印刷的堆信息来看,为什么新一代只有18m?其他2m去哪儿了?不用担心,就是这样。新一代=从 +到= 16 + 2 + 2 = 20m。可以看出,新一代的内存空间确实是根据XMN参数分配的。此处指定了SurvivorRatio = 8,因此,Eden的新一代空间= 8/10 = 8/10 * 20 = 16m。新一代空间从= = 1/10 = 1/10 * 20 = 2m。
堆信息中新一代的总计18432k计算如下:伊甸园 + 1幸存者= 16384K + 2048k = 18432k,约为18m。
由于JVM每次仅使用Eden和New Generation的幸存者,因此新一代中的实际可用内存空间是指定的记忆空间的90%。
因此,我们可以知道,这里新一代的内存空间是指新一代可用的总存储空间,而不是整个新一代的空间大小。
另外,可以看出,旧一代的记忆空间为40960k(约40m),堆大小=新一代 +旧一代。因此,在这里,旧一代=堆大小 - 年轻一代= 60-20 = 40m。
最后,此处还指定了permize = 30m。 Permgen是永久一代(方法区域)。它还有一个名为Non-Heap的名称。它主要用于存储类文件信息,常数,静态变量等。由JVM加载。