jvm设置方法区大小的参数

jdk7及以前:

通过-XX:PermSize 来设置永久代初始分配空间,默认值是20.75m
-XX:MaxPermSize来设定永久代最大可分配空间,32位是64m,64位是82m

jdk8及之后:

通过-XX:MetaspaceSize 来设置永久代初始分配空间,默认值是21m
-XX:MaxMetaspaceSize来设定永久代最大可分配空间,值为-1

由于没有上限,因此当本机内存耗尽时,会抛出oom的错误,对于起始值21m来说,如果所使用的内存超过这个值,则会触发full gc卸载没用的类,之后将会重置这个初始值,新的初始值的高低在于gc后释放了多少的空间,释放得少则提升这个初始值,释放得多则降低这个初始值。因此在实际的开发场景中,为了减少full gc的频率,会将这个初始值设置大一些。

代码示例:
通过for循环不停创建类,直到溢出为止。
设置jvm参数:-XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m

package com.lydon.test;


import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;


public class OOMTest extends ClassLoader{
    
    


    public static void main(String[] args) {
    
    
        int j=0;
        OOMTest test =new OOMTest();


        try{
    
    
            for (int i = 0; i <100000 ; i++) {
    
    
                ClassWriter classWriter=new ClassWriter(0);
                //指明版本号,修饰符,类型,包名,父类,接口
                classWriter.visit(Opcodes.V1_8,Opcodes.ACC_PUBLIC,"Class"+i,"com.lydon.test","java/lang/Object",null);
                byte[] code=classWriter.toByteArray();
                test.defineClass("Class"+i,code,0,code.length);
                j++;
            }
        }catch (Exception e){
    
    
            e.printStackTrace();
        }finally {
    
    
            System.out.println(j);
        }
    }
}

输出结果:

D:\Java\jdk1.8.0_121\bin\java.exe -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m "-javaagent:D:\IntelliJ IDEA 2021.1\lib\idea_rt.jar=63745:D:\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath D:\Java\jdk1.8.0_121\jre\lib\charsets.jar;D:\Java\jdk1.8.0_121\jre\lib\deploy.jar;D:\Java\jdk1.8.0_121\jre\lib\ext\access-bridge-64.jar;D:\Java\jdk1.8.0_121\jre\lib\ext\cldrdata.jar;D:\Java\jdk1.8.0_121\jre\lib\ext\dnsns.jar;D:\Java\jdk1.8.0_121\jre\lib\ext\jaccess.jar;D:\Java\jdk1.8.0_121\jre\lib\ext\jfxrt.jar;D:\Java\jdk1.8.0_121\jre\lib\ext\localedata.jar;D:\Java\jdk1.8.0_121\jre\lib\ext\nashorn.jar;D:\Java\jdk1.8.0_121\jre\lib\ext\sunec.jar;D:\Java\jdk1.8.0_121\jre\lib\ext\sunjce_provider.jar;D:\Java\jdk1.8.0_121\jre\lib\ext\sunmscapi.jar;D:\Java\jdk1.8.0_121\jre\lib\ext\sunpkcs11.jar;D:\Java\jdk1.8.0_121\jre\lib\ext\zipfs.jar;D:\Java\jdk1.8.0_121\jre\lib\javaws.jar;D:\Java\jdk1.8.0_121\jre\lib\jce.jar;D:\Java\jdk1.8.0_121\jre\lib\jfr.jar;D:\Java\jdk1.8.0_121\jre\lib\jfxswt.jar;D:\Java\jdk1.8.0_121\jre\lib\jsse.jar;D:\Java\jdk1.8.0_121\jre\lib\management-agent.jar;D:\Java\jdk1.8.0_121\jre\lib\plugin.jar;D:\Java\jdk1.8.0_121\jre\lib\resources.jar;D:\Java\jdk1.8.0_121\jre\lib\rt.jar;D:\workspace\jvm-demo\chapters09\target\classes com.lydon.test.OOMTest
8271
Exception in thread "main" java.lang.OutOfMemoryError: Metaspace
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
    at com.lydon.test.OOMTest.main(OOMTest.java:18)


Process finished with exit code 1

猜你喜欢

转载自blog.csdn.net/lyd135364/article/details/121151382