JVM内存结构--元空间学习记录

参考: JDK8的JVM内存结构,元空间替代永久代成为方法区及常量池的变化

元空间MetaSapce代替永久代PermGen

1. 为什么废除永久代?

1.1 官方说明:

参照JEP122:http://openjdk.java.net/jeps/122,原文截取:

Motivation
This is part of the JRockit and Hotspot convergence effort. JRockit customers do not need to configure the permanent generation (since JRockit does not have a permanent generation) and are accustomed to not configuring the permanent generation.
即:移除永久代是为融合HotSpot JVM与JRockit VM而做出的努力,因为JRockit没有永久代,不需要配置永久代。

1.2 永久代的使用中存在的一些问题

  • 字符串常量池存在“永久代”中,容易出现性能问题和OOM(OutOfMemoryError内存溢出);
  • 类和方法的信息大小难以确定,给“永久代”的大小指定带来困难;
  • 永久代会为GC带来不必要的复杂,在“永久代”中,元数据可能会伴随full gc发生而移动。

2 元空间内存结构

元空间属于直接内存 ,而非JVM分配的内存。
示意图:
JVM内存模型

3. 元空间与方法区

1. 什么是方法区

在java虚拟机中,方法区是可供各线程共享的运行时内存区域。

在不同的JDK版本中,方法区中存储的数据是不一样的。

在JDK1.6及以前,运行时常量池是方法区的一个部分,同时方法区里面存储了类的元数据信息、静态变量、即时编译器编译后的代码(比如Spring使用IOC或者AOP创建bean时,或者使用cglib,反射的形式动态生成class信息等)等等。

在JDK1.7及以后,JVM已经将运行时常量池从方法区中移了出来,在JVM堆开辟了一块区域存放常量池。

而现在的JDK1.8由于废除了永久代, 原先在方法去里的数据大都存到了元空间

2. 常量池随永久代的变化

几种常量池:

(1)静态常量池:即*.class文件中的常量池,在Class文件结构中,最头的4个字节存储魔数,用于确定一个文件是否能被JVM接受,接着4个字节用于存储版本号,前2个为次版本号,后2个主版本号,再接着是用于存放常量的常量池,由于常量的数量是不固定的,所以常量池的入口放置一个U2类型的数据(constant_pool_count)存储常量池容量计数值。

这种常量池占用class文件绝大部分空间,主要用于存放两大类常量:字面量和符号引用量,字面量相当于Java语言层面常量的概念,如文本字符串、基础数据、声明为final的常值等;符号引用则属于编译原理方面的概念,包括了如下三种类型的常量:类和接口的全限定名、字段名称描述符、方法名称描述符。类的加载过程中的链接部分的解析步骤就是把符号引用替换为直接引用,即把那些描述符(名字)替换为能直接定位到字段、方法的引用或句柄(地址)。

(2)运行时常量池:虚拟机会将各个class文件中的常量池载入到运行时常量池中,即编译期间生成的字面量、符号引用,总之就是装载class文件。为什么它叫运行时常量池呢?因为这个常量池在运行时,里面的常量是可以增加的。如:“+”连接字符生成新字符后调用 intern()方法、生成基础数据的包装类型等等。

(3)字符串常量池 :字符串常量池可以理解为是分担了部分运行时常量池的工作。加载时,对于class文件的静态常量池,如果是字符串就会被装到字符串常量池中。

(4)整型常量池:Integer,类似字符串常量池。管理-128–127的常量。类似的还有Character、Long等常量池(基本数据类型没有,Double、Float也没有常量池)

总结

class文件有常量池存放这个类的信息,占用了大多数空间。但是运行时所有加载进来的class文件的常量池的东西都要放到运行时常量池,这个运行时常量池还可以在运行时添加常量。字符串常量池、Integer等常量池则是分担了运行时常量池的工作,

在永久代移除后,字符串常量池也不再放在永久代了,但是也没有放到新的方法区—元空间里,而是留在了堆里(为了方便回收?)。运行时常量池当然是随着搬家到了元空间里,毕竟它是装类的重要信息的,有它的地方才称得上是方法区。

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不谷尉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值