JVM默认运行参数
支持JVM运行的重要配置,根据操作系统/物理硬件不同而不同
分为三类参数:
类型
稳定性
举例
- 参数
标准参数,比较稳定
-version
-X 参数
非标准参数,不在所有VM通用
-Xmx
-XX 参数
非Stable参数,容易变更
-XX:MaxMetaspaceSize
下面使用-XX:+PrintFlagsFinal 显示堆内存的相关参数
C:\Users\Administrator>java -XX:+PrintFlagsFinal -version | findstr HeapSize
uintx ErgoHeapSizeLimit = 0 {product}
uintx HeapSizePerGCThread = 87241520 {product}
uintx InitialHeapSize := 161480704 {product}
uintx LargePageHeapSizeThreshold = 134217728 {product}
uintx MaxHeapSize := 2571108352 {product}
openjdk version "1.8.0_202-release"
OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)
OpenJDK 64-Bit Server VM (build 25.202-b03, mixed mode)
下面来演示如何在程序中配置相关参数
程序启动的两类参数
程序参数:程序需要,存储在main函数的形参数组中
虚拟机参数:更改默认配置,用以指导进程运行
JVM参数M配置
堆(Heap)
共享,内存大户,存储所有的对象和数组
-Xms 初始堆值,-Xmx最大堆值
下面代码设置 VM options 的参数为: -Xmx5M (见上图),运行后出现OutOfMemoryError异常
public static void main(String[] args) {
List users = new ArrayList<>();
while (true){
users.add(new User());
System.out.println(users.size());
}
}
输出:
.
.
.
152694
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.nio.CharBuffer.wrap(CharBuffer.java:373)
JVM 栈(JVM Stack)
线程私有,存储类中每个方法的内容
-Xss 最大栈值
下面代码设置 VM options 的参数为: -Xss1M,运行后出现StackOverflowError异常
public class MyClass {
private int count = 1;
public void sum(){
count ++;
System.out.println(count);
sum();//递归调用
}
public static void main(String[] args) {
new MyClass().sum();
}
}
输出:
.
.
.
10503
Exception in thread "main" java.lang.StackOverflowError
下面代码设置 VM options 的参数为: -Xmx5M -Xss1M,运行后出现OutOfMemoryError异常
public class MyClass {
public static void main(String[] args) {
int num = 0;
while (true){
num ++;
System.out.println(num);
new MyThread().start();
}
}
static class MyThread extends Thread{
@Override
public void run() {
long a1,a2,a3,a4,a5,a6,a7,a8,a9,a10;
a1=a2=a3=a4=a5=a6=a7=a8=a9=a10=0;
while (true){
try {
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
}
输出:
.
.
.
8191
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
方法区(Method Area)
存储类信息、常量池等
1.7及以前,永久区(Perm),-XX:PermSize, -XX:MaxPermSize
1.8及以后,元数据区,-XX:MetaspaceSize, -XX:MaxMetaspaceSize
C:\Users\Administrator>java -XX:+PrintFlagsFinal -version | findstr Meta
uintx InitialBootClassLoaderMetaspaceSize = 4194304 {product}
uintx MaxMetaspaceExpansion = 5451776 {product}
uintx MaxMetaspaceFreeRatio = 70 {product}
uintx MaxMetaspaceSize = 4294901760 {product}
uintx MetaspaceSize = 21807104 {pd product}
uintx MinMetaspaceExpansion = 339968 {product}
uintx MinMetaspaceFreeRatio = 40 {product}
bool TraceMetadataHumongousAllocation = false {product}
bool UseLargePagesInMetaspace = false {product}
openjdk version "1.8.0_202-release"
OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)
OpenJDK 64-Bit Server VM (build 25.202-b03, mixed mode)
说明:
MaxMetaspaceSize:用于设置metaspace区域的最大值。
MetaspaceSize:表示metaspace首次使用不够而触发FGC的阈值,只对触发起作用。
-XX:MaxMetaspaceSize 最大元数据空间值
下面代码设置 VM options 的参数为: -XX:MaxMetaspaceSize=9M,运行后出现OutOfMemoryError异常
public static void generateClass(){
String className = "Hello";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
System.out.println(i);
String realClassName = className + i;
sb.append("class " + realClassName + "{\n");
sb.append("public static void main(String[] args){\n");
sb.append("System.out.print(\"hello world\"); \n");
sb.append("}\n");
sb.append("}");
try {
//使用第三方库InMemoryJavaCompiler(https://github.com/trung/InMemoryJavaCompiler)
Class> helloClass = InMemoryJavaCompiler.newInstance().compile(realClassName, sb.toString());
}catch (Exception e){
e.printStackTrace();
}
}
}
输出:
0
Exception in thread "main" java.lang.OutOfMemoryError: Compressed class space
总结
了解JVM的运行参数有哪些
根据异常信息,调整相应的内存参数