jvm设置方法区大小的参数

本文介绍了JDK8以后Metaspace的概念,对比了与JDK7之前的PermGen的区别。通过代码示例展示了如何通过创建大量类导致Metaspace溢出,解释了MetaspaceSize和MaxMetaspaceSize参数的含义,以及当Metaspace空间耗尽时如何触发Full GC。同时,讨论了如何调整初始值以减少Full GC的发生。
摘要由CSDN通过智能技术生成

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值