【JVM】运行时数据区-方法区

Jdk8以后为什么改用元空间来实现方法区

方法区的演进

Jdk7及以前:永久代实现
jdk8开始:元空间实现用的是本地物理内存,因此元空间的限制可以不受JVM的内存限制,决定于物理内存

Jdk7及以前:
初始化值默认为20.75M,32位机最大值为64M,64位最大值为82M

Jdk8及以后:
查看元空间大小的命令:
jinfo -flag MetaspaceSize 95560
jinfo -flag MaxMetaspaceSize 95560

在这里插入图片描述

设置元空间大小命令:
-XX:MetaspaceSize=100m -XX:MaxMetaspaceSize=100m

在这里插入图片描述

  • 1、一般而言,方法区不用设置最大空间限制,只设置初始化大小MetaspaceSize
  • 2、MetaspaceSize是动态变化的,一旦触及这个水位线,就会触发一次FullGC,若释放的元空间不多,则适当调高这个值;若释放空间很多,则适当降低该值;为了避免频繁FullGC,MetaspaceSize一般需要设置为一个相对较高的值;

方法区的内部结构:

  • 1、《深入理解Java虚拟机》描述经典方法区:存储已被虚拟机加载的类信息、运行时常量池、静态变量、即时编译器编译后的代码缓存等。

在这里插入图片描述

  • 2、class文件载入到方法区后,才会有ClassLoader对象,反编译class文件:javap -v -p HelloWorld.class >test.txt
  • 3、Class文件加载到方法区后的模样:参考《自己动手写Java虚拟机》:

类信息:

在这里插入图片描述

字段信息:

在这里插入图片描述

方法信息:

在这里插入图片描述

运行时常量池:

在这里插入图片描述

  • 符号引用:Constant classRef,methodRef ,fieldRef, consts[n]={classRef,methodRef ,fieldRef},通过索引访问
  • 直接引用:classRef=*student,fieldRef=*name,methodRef=*main()

方法区的使用示例与理解:

public class Student{
    private static int id=11;
    private String name;
    private final int age=9;

    public static void main(String[] args) {
        int a=1;
        int b=2;
        System.out.println(a+b);
    }
}

加载(准备材料)——执行(main方法开始)
串联一下前面的类加载的内容,解释一下只有Class文件运行时从加载到执行的过程:

  • 1、我们前面说类加载时Class文件经历了加载、链接(校验、准备置零、解析符号引用)、初始化静态变量的阶段;
  • 2、经历完这些阶段后,方法区中也就新建好Student类、字段、方法信息、把Class文件的常量池解析为运行时常量池(consts[n]),并创建一个Student类的Class对象,同时初始化好静态变量,并把运行时常量池中的符号引用转为直接引用;
  • 3、前两步为准备材料阶段,接下来便会从main()方法开始执行方法的命令;

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值