简单理解jdk1.8中的方法区

JVM里的方法区是线程共享的内存区域,存储已被虚拟机加载的类信息、常量、静态变量,静态代码块、即时编译器(JIT Compiler)编译后的代码数据等。

简单而言,就是存储类结构信息,信息里包含了有常量池信息,加载到JVM之后就变成了运行时常量池。还有至于字符串常量池(串池)在jdk1.8之前和之后位置不同,1.8之前跟随运行时常量池在方法区,在1.8之后就独自在堆内存中了。

【重点】方法区是一个逻辑概念,其具体实现为jdk1.8的元空间与jdk1.8之前的永久代,他们之间最大的区别在于:元空间并不在JVM管理的内存中,而是使用本地内存。

替代的原因
1、1.8之前,字符串存在永久代中,容易出现性能问题和内存溢出,只有fullGC才会扫描清理到永久代,效率偏低。字符串常量
2、类及方法的信息等比较难确定其大小,放入系统内存更为合适

在这里插入图片描述
以1.8举例为例,我们在这里设置元空间大小为8m,且重复创建类,类的信息是放在方法区的,所以看看这里方法区的实现是什么。
设置大小-XX:MaxMetaspaceSize=8m
在这里插入图片描述
编写代码

public class HttpController extends ClassLoader {
    public static void main(String[] args) throws Exception {
        HttpController httpController = new HttpController();
        for (int i = 0; i <100000; i++) {
            ClassWriter cw = new ClassWriter(0);
            cw.visit(Opcodes.V1_8,Opcodes.ACC_PUBLIC,"Class"+i,null,"java/lang/Object",null);
            byte[] bytes = cw.toByteArray();
            httpController.defineClass("Class"+i,bytes,0,bytes.length);
        }
   }
}

结果就是

Exception in thread "main" java.lang.OutOfMemoryError: Metaspace
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)

内存溢出错误,这里是元空间Metaspace的内存溢出。这就证明了1.8的时候类的结构信息确实放在了元空间中。

【完,喜欢就点个赞呗】

正在去BAT的路上修行

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值