运行时数据区-方法区

方法区(实现方式:永久代|元空间)

首先明确:只有Hotspot才有方法区的概念。其他虚拟机是不存在这一概念的。

方法区是规范,是逻辑概念,原则上如何实现方法区属于虚拟机实现细节,不受《Java虚拟机规范》管束,并不要求统一。
所以永久代和元空间都是HotSpot实现方法区这一概念的方式。

  • Java8之前的版本,用永久代实现方法区;
  • Java8之后的版本,用元空间实现方法区;

元空间与永久代最大的区别在于:
永久代在堆内存中,元空间在堆外

JVM在1.8时用元空间代替永久代的原因
随着Web领域的发展,Java程序变得越来越大,需要加载的内容也越来越多,永久代是放在堆内存中的,占用的是堆内存空间,所以容易OOM
而元空间放在本地内存中,使用元空间之后,就可以将数据直接存储在本地内存当中,减少了OOM的可能性。

方法区内部结构

方法区主要是用来存放已被虚拟机加载的「类相关信息」:包括类信息、常量池

  • 类信息又包括了类的版本、字段、方法、接口和父类等信息。
  • 常量池又可以分「静态常量池」和「运行时常量池」
    • 静态常量池主要存储的是「字面量」以及「符号引用」等信息,静态常量池也包括了我们说的「字符串常量池」。
    • 「运行时常量池」存储的是「类加载」时生成的「直接引用」等信息。

从「逻辑分区」的角度而言「常量池」是属于「方法区」的
但从「物理分区」来说,是属于堆的。因为从「JDK7」以后,就已经把「运行时常量池」和「静态常量池」转移到了「堆」内存中进行存储

下面详解类信息:

类型信息

对每个加载的类型(类class、接口interface、枚举enum、注解annotation)
JVm必须在方法区中存储以下类型信息

  • 这个类型的完整有效名称(包名.类名)
  • 这个类型直接父类的完整有效名
  • 这个类型的修饰符(public,abstract,final的某个子集)
  • 这个类型直接接口的一个有序列表

属性信息

包括:
属性名称
域类型(8种基本类型,引用类型等)
域修饰符(public,private,protected,static,final,volatile)

方法信息

JVM必须保存所有方法的以下信息,同域信息一样包括声明顺序:

  • 方法名称
  • 方法的返回类型(或void)
  • 方法参数的数量和类型(按顺序)
  • 方法的修饰符(public,private,protected,static,final,synchronized,native,abstract的一个子集)
  • 方法的字节码(bytecodes)、操作数栈、局部变量表及大小
  • 异常表
    包括:每个异常处理的开始位置、结束位置、代码处理在程序计数器中的偏移地址、被捕获的异常类的常量池索引

方法区的演进细节

Hotspot中方法区的变化:
JDK6的时候
在这里插入图片描述

JDK7的时候
在这里插入图片描述
JDK8的时候,元空间大小只受物理内存影响
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值