41.JVM方法区的内部结构(方法区中存储的是什么)

1.方法区内部结构

Java代码被编译成字节码文件之后,通过类加载器被加载到运行时数据区。其中,方法区主要存储的是类型的相关信息以及运行时常量池。对于字符串常量,根据JDK版本的不同,有的放到了方法区,有的没有。
在这里插入图片描述
方法区中存放的是类型信息、常量、静态变量、即时编译器编译后的代码缓存、域信息、方法信息等。随着JDK的发展,方法区中存放的内容也在发生变化。并不绝对。通常情况下放的是这些内容。
在这里插入图片描述
1.类型信息
在这里插入图片描述
2.域信息 ==> 成员变量信息
在这里插入图片描述
3.方法信息
在这里插入图片描述
例子:下面是一个Java程序的字节码文件通过javap反编译之后得到的输出。
class文件中的类型信息、域信息、方法信息都会被类加载器加载到方法区中。

  Last modified 2020-4-22; size 1626 bytes
  MD5 checksum 69643a16925bb67a96f54050375c75d0
  Compiled from "MethodInnerStrucTest.java"
  //类型信息会被加载到方法区
public class com.atguigu.java.MethodInnerStrucTest extends java.lang.Object // 类的全限定名以及父类
implements java.lang.Comparable<java.lang.String>, java.io.Serializable //类实现的接口信息
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER // 类的权限修饰符
Constant pool:
   #1 = Methodref          #18.#52        // java/lang/Object."<init>":()V
   #2 = Fieldref           #17.#53        // com/atguigu/java/MethodInnerStrucTest.num:I
   #3 = Fieldref           #54.#55        // java/lang/System.out:Ljava/io/PrintStream;
   ...
{
  //域信息会被加载到方法区
  public int num; // 域名称
    descriptor: I // 域类型
    flags: ACC_PUBLIC // 域权限

  private static java.lang.String str;
    descriptor: Ljava/lang/String;
    flags: ACC_PRIVATE, ACC_STATIC

  //方法信息会被加载到方法区
  public com.atguigu.java.MethodInnerStrucTest(); // 方法名称
    descriptor: ()V //方法参数及方法返回值类型
    flags: ACC_PUBLIC //方法权限修饰符
    Code: //方法对应的字节码
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: bipush        10
         7: putfield      #2                  // Field num:I
        10: return
      LineNumberTable:
        line 10: 0
        line 12: 4
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      11     0  this   Lcom/atguigu/java/MethodInnerStrucTest;
            ......
}
Signature: #49                          // Ljava/lang/Object;Ljava/lang/Comparable<Ljava/lang/String;>;Ljava/io/Serializable;
SourceFile: "MethodInnerStrucTest.java"

2.non-final的类变量与final的类变量初始化的时间

non-final的类变量:就是static的成员变量。
在这里插入图片描述
final的类变量:就是static final的成员变量。
在这里插入图片描述

初始化的区别:初始化的时间不同,non-final的类变量在类加载的第二个阶段(链接阶段)的准备阶段被赋默认的初始值,然后再类加载的第三个阶段(初始化阶段)被显示初始化(也就是赋值为代码中写的值)。
比如: 定义一个成员变量a, public static int a = 7; a在链接阶段的准备阶段被赋默认值0;然后再初始化阶段被显示初始化为7

final的类变量是在编译阶段就被显示初始化了。
比如:定义一个成员变量, public static final int a = 7;a在代码被编译成字节码文件的时候就被赋值为7了。

更多JVM文章请访问我的JVM专栏:
https://blog.csdn.net/u011069294/category_10113093.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值