运行时数据区-方法区(Method Area)- 方法区内部结构
方法区(Method Area)存储了什么?
《深入理解Java虚拟机》书中方法区(Method Area)存储内容描述如下:
它用于存储已经被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等
类型信息
每个类加载的类型(类class、接口interface、枚举enum、注解annotation),JVM必须在方法区中存储以下类型信息:
- 这个类型的完整的有效类名(类全名=包名.类名)
- 这个类型直接父类的完整有效名(对于interface或者java.lang.Object都没有父类)
- 这个类型的访问修饰符(public、abstract,final的某个子集)
- 这个类型直接接口的有序列表
域(Feild)信息
- JVM必须在方法区中保存类型所有的域相关的信息以及域的声明顺序
- 域的相关信息包括:域名称、域类型、域修饰符(public、private、protected、static、final、volatile、transient的某个子集)
方法(Method)信息
JVM必须保存所有方法的以下信息,和域信息一样包括声明顺序:
- 方法名称
- 方法返回值类型(或者void)
- 方法参数的数量和类型
- 方法访问修饰符(public、private、protected、static、final、native、syncchronized等)
- 方法的字节码(bytecodes)、操作数栈、局部变量表及大小(bastract和native除外)
- 异常表(abstract和native除外)
- 每个异常处理的开始位置、结束位置、代码处理在程序计数器中的偏移地址、被捕获的异常类的常量池索引
事例代码
public class MethoInnerStrucdTest implements Comparable<String>, Serializable {
//一般变量
public int i = 0;
//静态变量
private static String str = "测试类的内部结构";
//系统默认的构造方法(没写)
//普通方法
private void test1() {
int count = 20;
System.out.println("cpunt=" + count);
}
//静态方法
public static int test2(int cal) {
int result = 0;
try {
int value = 30;
result = value / cal;
} catch (Error error) {
error.printStackTrace();
}
return result;
}
@Override
public int compareTo(String o) {
return 0;
}
}
javac编译之后,用javap -p -v反编译(-p能够反编译出private的属性)
E:\WorkingSpace\IdeaProjects\demo002\target\classes\com\booyue\tlh>javap -v -p MethoInnerStrucdTest.class
Classfile /E:/WorkingSpace/IdeaProjects/demo002/target/classes/com/booyue/tlh/MethoInnerStrucdTest.class
Last modified 2021-5-15; size 1610 bytes
MD5 checksum 5beaba71e01d229fd8c42ea0e390740b
Compiled from "MethoInnerStrucdTest.java"
public class com.booyue.tlh.MethoInnerStrucdTest extends java.lang.Object implements java.lang.Comparable<java.lang.String>, java.io.Serializable
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #18.#52 // java/lang/Object."<init>":()V
#2 = Fieldref #17.#53 // com/booyue/tlh/MethoInnerStrucdTest.i:I
#3 = Fieldref #54.#55 // java/lang/System.out:Ljava/io/PrintStream;
#4 = Class #56 // java/lang/StringBuilder
#5 = Methodref #4.#52 // java/lang/StringBuilder."<init>":()V
#6 = String #57 // cpunt=
#7 = Methodref #4.#58 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#8 = Methodref #4.#59 // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
#9 = Methodref #4.#60 // java/lang/StringBuilder.toString:()Ljava/lang/String;
#10 = Methodref #61.#62 // java/io/PrintStream.println:(Ljava/lang/String;)V
#11 = Class #63 // java/lang/Error
#12 = Methodref #11.#64 // java/lang/Error.printStackTrace:()V
#13 = Class #65 // java/lang/String
#14 = Methodref #17.#66 // com/booyue/tlh/MethoInnerStrucdTest.compareTo:(Ljava/lang/String;)I
#15 = String #67 // 测试类的内部结构
#16 = Fieldref #17.#68 // com/booyue/tlh/MethoInnerStrucdTest.str:Ljava/lang/String;
#17 = Class #69 // com/booyue/tlh/MethoInnerStrucdTest
#18 = Class #70 // java/lang/Object
#19 = Class #71 // java/lang/Comparable
#20 = Class #72 // java/io/Serializable
#21 = Utf8 i
#22 = Utf8 I
#23 = Utf8 str
#24 = Utf8 Ljava/lang/String;
#25 = Utf8 <init>
#26 = Utf8 ()V
#27 = Utf8 Code
#28 = Utf8 LineNumberTable
#29 = Utf8 LocalVariableTable
#30 = Utf8 this
#31 = Utf8 Lcom/booyue/tlh/MethoInnerStrucdTest;
#32 = Utf8 test1
#33 = Utf8 count
#34 = Utf8 test2
#35 = Utf8 (I)I
#36 = Utf8 value
#37 = Utf8 error
#38 = Utf8 Ljava/lang/Error;
#39 = Utf8 cal
#40 = Utf8 result
#41 = Utf8 StackMapTable
#42 = Class #63 // java/lang/Error
#43 = Utf8 compareTo
#44 = Utf8 (Ljava/lang/String;)I
#45 = Utf8 o
#46 = Utf8 (Ljava/lang/Object;)I
#47 = Utf8 <clinit>
#48 = Utf8 Signature
#49 = Utf8 Ljava/lang/Object;Ljava/lang/Comparable<Ljava/lang/String;>;Ljava/io/Serializable;
#50 = Utf8 SourceFile
#51 = Utf8 MethoInnerStrucdTest.java
#52 = NameAndType #25:#26 // "<init>":()V
#53 = NameAndType #21:#22 // i:I
#54 = Class #73 // java/lang/System
#55 = NameAndType #74:#75 // out:Ljava/io/PrintStream;
#56 = Utf8 java/lang/StringBuilder
#57 = Utf8 cpunt=
#58 = NameAndType #76:#77 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#59 = NameAndType #76:#78 // append:(I)Ljava/lang/StringBuilder;
#60 = NameAndType #79:#80 // toString:()Ljava/lang/String;
#61 = Class #81 // java/io/PrintStream
#62 = NameAndType #82:#83 // println:(Ljava/lang/String;)V
#63 = Utf8 java/lang/Error
#64 = NameAndType #84:#26 // printStackTrace:()V
#65 = Utf8 java/lang/String
#66 = NameAndType #43:#44 // compareTo:(Ljava/lang/String;)I
#67 = Utf8 测试类的内部结构
#68 = NameAndType #23:#24 // str:Ljava/lang/String;
#69 = Utf8 com/booyue/tlh/MethoInnerStrucdTest
#70 = Utf8 java/lang/Object
#71 = Utf8 java/lang/Comparable
#72 = Utf8 java/io/Serializable
#73 = Utf8 java/lang/System
#74 = Utf8 out
#75 = Utf8 Ljava/io/PrintStream;
#76 = Utf8 append
#77 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
#78 = Utf8 (I)Ljava/lang/StringBuilder;
#79 = Utf8 toString
#80 = Utf8 ()Ljava/lang/String;
#81 = Utf8 java/io/PrintStream
#82 = Utf8 println
#83 = Utf8 (Ljava/lang/String;)V
#84 = Utf8 printStackTrace
{
public int i;
descriptor: I
flags: ACC_PUBLIC
private static java.lang.String str;
descriptor: Ljava/lang/String;
flags: ACC_PRIVATE, ACC_STATIC
public com.booyue.tlh.MethoInnerStrucdTest();
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: iconst_0
6: putfield #2 // Field i:I
9: return
LineNumberTable:
line 5: 0
line 8: 4
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this Lcom/booyue/tlh/MethoInnerStrucdTest;
private void test1();
descriptor: ()V
flags: ACC_PRIVATE
Code:
stack=3, locals=2, args_size=1
0: bipush 20
2: istore_1
3: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
6: new #4 // class java/lang/StringBuilder
9: dup
10: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V
13: ldc #6 // String cpunt=
15: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
18: iload_1
19: invokevirtual #8 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
22: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
25: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
28: return
LineNumberTable:
line 16: 0
line 17: 3
line 18: 28
LocalVariableTable:
Start Length Slot Name Signature
0 29 0 this Lcom/booyue/tlh/MethoInnerStrucdTest;
3 26 1 count I
public static int test2(int);
descriptor: (I)I
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=3, args_size=1
0: iconst_0
1: istore_1
2: bipush 30
4: istore_2
5: iload_2
6: iload_0
7: idiv
8: istore_1
9: goto 17
12: astore_2
13: aload_2
14: invokevirtual #12 // Method java/lang/Error.printStackTrace:()V
17: iload_1
18: ireturn
Exception table:
from to target type
2 9 12 Class java/lang/Error
LineNumberTable:
line 22: 0
line 24: 2
line 25: 5
line 28: 9
line 26: 12
line 27: 13
line 29: 17
LocalVariableTable:
Start Length Slot Name Signature
5 4 2 value I
13 4 2 error Ljava/lang/Error;
0 19 0 cal I
2 17 1 result I
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 12
locals = [ int, int ]
stack = [ class java/lang/Error ]
frame_type = 4 /* same */
public int compareTo(java.lang.String);
descriptor: (Ljava/lang/String;)I
flags: ACC_PUBLIC
Code:
stack=1, locals=2, args_size=2
0: iconst_0
1: ireturn
LineNumberTable:
line 34: 0
LocalVariableTable:
Start Length Slot Name Signature
0 2 0 this Lcom/booyue/tlh/MethoInnerStrucdTest;
0 2 1 o Ljava/lang/String;
public int compareTo(java.lang.Object);
descriptor: (Ljava/lang/Object;)I
flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: aload_1
2: checkcast #13 // class java/lang/String
5: invokevirtual #14 // Method compareTo:(Ljava/lang/String;)I
8: ireturn
LineNumberTable:
line 5: 0
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 this Lcom/booyue/tlh/MethoInnerStrucdTest;
static {};
descriptor: ()V
flags: ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: ldc #15 // String 测试类的内部结构
2: putstatic #16 // Field str:Ljava/lang/String;
5: return
LineNumberTable:
line 10: 0
}
Signature: #49 // Ljava/lang/Object;Ljava/lang/Comparable<Ljava/lang/String;>;Ljava/io/Serializable;
SourceFile: "MethoInnerStrucdTest.java"