《剑指JVM》——第8章——方法区的内部结构——方法区3——运行时数据区篇22

🌈hello,你好鸭,我是Ethan,西安电子科技大学大三在读,很高兴你能来阅读。

✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。
🏃人生之义,在于追求,不在成败,勤通大道。加油呀!

🔥个人主页:Ethan Yankang
🔥推荐:史上最强八股文||一分钟看完我的几百篇博客

🔥温馨提示:划到文末发现专栏彩蛋   点击这里直接传送

🔥本篇概览:详细讲解了第8章——方法区的内部结构,并详细用代码实际观测了方法区的内部结构。🌈⭕🔥


【计算机领域一切迷惑的源头都是基本概念的模糊,算法除外】


🔥 《剑指JVM》序言-CSDN博客

🔥 《剑指JVM》全书-CSDN博客


🌈章节引出

前一篇章:《剑指JVM》——第8章——方法区的理解——方法区2——运行时数据区篇22-CSDN博客

🌈章节速览


1.方法区的内部结构

1.1什么时候放入数据

方法区内部结构如图8-14所示。Java源代码编译之后生成class文件,经过类加载器把class 文件中的内容加载到JVM 运行时数据区。class 文件中的一部分信息加载到方法区,比如类 class、接口 interface、枚举 enum、注解 annotation 以及运行时常量池等类型信息。

1.2存放什么样的数据

上面我们从类加载到运行时数据区的角度说明了方法区什么时候放入数据,下面我们比较详细地说明方法区中存放什么样的数据。方法区和Java堆一样,是各个线程共享的内存区域它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存。如图8-15所示。不同的虚拟机实现,部分信息的存储位置是有变化的,我们上面讲到的这些信息存放在方法区是比较经典的说法。

接下来对方法区的存放的数据进行详细的介绍:


2.方法区中数据的详细介绍


下面我们先介绍类型信息、域信息和方法信息中存储的内容分别是什么。


2.1.类型信息


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

  • 完整有效全类名,包括包名和类名。
  • 直接父类的完整有效名(对于interface 或是java.lang.Object,都没有父类)。
  • 修饰符(public、abstract、fnal的某个子集)。
  • 直接接口的一个有序列表。


2.2.域信息(field)

即类中的成员变量
JVM 必须在方法区中保存类型的所有域的相关信息以及域的声明顺序。

  • 域的相关信息包括域名称、域类型、域修饰符(public、private、protected、static、final、volatile、transient 的某个子集)。


2.3.方法信息

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

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

3.代码测试方法区的内部结构

3.0测试代码

public class MethodInnerStrucTest extends Object implements Comparable<String>, Serializable {
    // 属性
    public int num = 10;
    private static String str = "测试方法区的内部结构";

    // 方法
    public void test1() {
        int count = 20;
        System.out.println("count=" + count);
    }

    public static int test2(int cal) {
        int result = 0;
        try {
            int value = 30;
            result = value + cal;  // 这里应该是加法运算,修改为 '+'
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public int compareTo(String o) {
        return 0;  // 这里需要根据具体的比较逻辑来实现,目前只是简单返回 0
    }
}

编译成class之后,反编译成字节码:

3.1类型信息

上述代码的 class 文件经反编译(使用命令javap -v -p MethodnnerStrucTest.class)之后的类型信息如下所示,可以看到完整有效全类名为com,atguigu.MethodlnnerStrucTest;父类为java,lang.Object;实现的接口为java.lang.Comparable<java.lang.String>;修饰符为 public。

3.2.域信息

域信息如下所示,其中包含两个域信息,分别是num和str。首先分析num的各项信息,num为域名称、I表示域类型为Integer、ACC_PUBLIC 表示域修饰符为public。接着分析str 的各项信息,str 为域名称、Ljava/lang/String 表示域类型为 String、ACC_PRIVATE 和 ACC_STATIC 表示域修饰符为 private static。

3.3方法信息

上述代码的 class 文件经反编译之后的test1()方法信息如下所示,可以看到方法名称是test1();()V表示返回值是 void;该方法没有参数,所以没有参数名称和类型;ACC PUBLIC表示方法修饰符是public;Code后面的字节码包括方法的字节码指令、操作数栈深度为 3、局部变量表大小为 2

 

无参构造器

除了test1()方法外,大家可以看到反编译文件中还有一个方法叫作MethodInnerStrucTest(),我们知道 Java 中如果不手动定义构造方法的话,Java 默认会提供一个无参的构造方法,在 class 文件反编译之后,可以看到无参构造方法信息如下所示。

异常表

最后,我们看到 test2()方法的信息中还存在一个异常表,如下所示,其中Exception table表示异常表。



💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖

热门专栏推荐

🌈🌈计算机科学入门系列                     关注走一波💕💕

🌈🌈CSAPP深入理解计算机原理        关注走一波💕💕

🌈🌈微服务项目之黑马头条                 关注走一波💕💕

🌈🌈redis深度项目之黑马点评            关注走一波💕💕

🌈🌈JAVA面试八股文系列专栏           关注走一波💕💕

🌈🌈JAVA基础试题集精讲                  关注走一波💕💕   

🌈🌈代码随想录精讲200题                  关注走一波💕💕


总栏

🌈🌈JAVA基础要夯牢                         关注走一波💕💕  

🌈🌈​​​​​​JAVA后端技术栈                          关注走一波💕💕  

🌈🌈JAVA面试八股文​​​​​​                          关注走一波💕💕  

🌈🌈JAVA项目(含源码深度剖析)    关注走一波💕💕  

🌈🌈计算机四件套                               关注走一波💕💕  

🌈🌈数据结构与算法                           ​关注走一波💕💕  

🌈🌈必知必会工具集                           关注走一波💕💕

🌈🌈书籍网课笔记汇总                       关注走一波💕💕         



📣非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞👍 关注❤收藏✅ 评论💬,大佬三连必回哦!thanks!!!
📚愿大家都能学有所得,功不唐捐!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值