java jvm 方法区_JVM 方法区

方法区与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

使用HotSpot虚拟机的用户,更愿意把方法区称为“永久代”,本质上两者并不等价,仅仅是因为HotSpot虚拟机的设计团队选择把GC分代收集至方法区,或者说用永久代来实现方法区而已。这样HotSpot的垃圾收集器可以像管理Java堆一样管理这部分内存,能省去专门为方法区编写内存管理代码的工作。

移除永久代的工作从JDK1.7就开始了。JDK1.7中,存储在永久代的部分数据就已经转移到了Java Heap或者是 Native Heap。但永久代仍存在于JDK1.7中,并没完全移除,譬如符号引用(Symbols)转移到了native heap;字面量(interned strings)转移到了java heap;类的静态变量(class statics)转移到了java heap。

元空间本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此默认情况下元空间的大小仅受本地内存限制。

即方法区里存放着类的版本、字段、方法、接口和常量池(存储字面量和符号引用)。

符号引用包括:1、类的权限定名;2、字段名和属性;3、方法名和属性。

acc6430cac8559de27802f69c01360eb.png

1、类型信息:

类的完整名称

类的直接父类的完整名称

类的直接实现接口的有序列表

类型标志(类类型还是接口类型)

类的修饰符(public private defautl abstract final static)

2、类型的常量池

存放该类型所用到的常量的有序集合,包括直接常量(字符串、整数、浮点数)和对其他类型、字段、方法的符号引用。

3、字段信息(该类声明的所有字段)

字段修饰符(public、peotect、private、default)

字段的类型

字段名称

4、方法信息

方法信息中包含类的所有方法。

方法修饰符

方法返回类型

方法名

方法参数个数、类型、顺序等

方法字节码

操作数栈和该方法在栈帧中的局部变量区大小

异常表

5、类变量(静态变量)

6、指向类加载器的引用

7、指向Class实例的引用

8、方法表

9、运行时常量池(Runtime Constant Pool)

总结:

HotSpot JVM中,永久代中用于存放类和方法的元数据以及常量池。每当一个类初次被加载的时候,它的元数据都会被放到永久代中。

永久代大小有限制,如果加载的类太多,很可能导致永久代内存溢出,即java.lang.OutOfMemoryError: PermGen。

Java 8中PermGen被移出HotSpot JVM了:

由于 PermGen 内存经常会溢出,引发恼人的 java.lang.OutOfMemoryError: PermGen,因此 JVM 的开发者希望这一块内存可以更灵活地被管理,不要再经常出现这样的 OOM

移除 PermGen 可以促进 HotSpot JVM 与 JRockit VM 的融合,因为 JRockit 没有永久代。

PermGen最终被移出,方法区移至Metaspace,字符串常量移至Java Heap。

JDK8把类的元数据放到本地堆内存(native heap)中,这一块区域就叫Metaspace,中文名叫元空间。

如果Metaspace的空间占用达到了设定的最大值,那么就会触发GC来收集死亡对象和类的加载器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值