复习整理的DAY24_方法区

首先,什么是方法区?

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

方法区包括静态变量 + 常量 + 类信息(构造方法/接口定义) + 运行时常量池。

我们经常谈论方法区与堆,那么方法区属于堆吗?

虚拟机规范中讲方法区看做是堆的逻辑部分,但是对于HotSpotJVM实现上,将堆和方法区分开,认为是两个不同的结构,方法区还有一个名字是非堆(Non-Heap)。

那么方法区的具体实现是什么呢?

jdk1.7及之前的永久代和jdk1.8及之后的元空间。

栈、堆、方法区的交互关系

(1)Test 类的 .class 信息存放在方法区中

(2)test 变量存放在 Java 栈的局部变量表中

(4)真正的 test 对象存放在 Java 堆中

(5)在 test 对象中,有个指针指向方法区中的 Test 类型数据,表明这个 test 对象是用方法区中的 Test 类 new 出来的

如图: 

方法区的虚拟机异常:

方法区的大小决定了可以保存的类的数量,如果定义了太多的类,导致方法区溢出,虚拟机会报出内存溢出错误——java.lang.OutofMemoryError:PermGen spce(jdk1.8以前),或java.lang.OutofMemoryError:Metaspace(jdk1.8及之后)

比如加载太多的第三方jar包,Tomcat部署的工程过多,大量动态生成反射类。

方法区内部结构:

jdk1.6方法区内部:                                             jdk1.8方法区内部:

 

注: jdk1.7中JVM把字符串常量区从方法区中移除了;JDK1.8中JVM把字符串常量池移入了堆中。

常量池:

常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据,是JVM的一块特殊的内存空间。

一个有效的字节码文件中除了包含类的版本信息、字段、方法以及接口等描述信息之外,还包括一项信息——常量池表(Constant Pool Table),包括各种字面量,以及对类型、域和方法的符号引用。

虚拟机根据这张常量池表找到要执行的类名、方法名、参数类型、字面量等类型。

运行时常量池:

什么是运行时常量池?

将字节码文件中的常量池加载到方法区就是运行时常量池。

运行时常量池是方法区的一部分。

变化:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值