04.Metaspace
Metaspace

方法区
方法区是所有线程共享的内存区域,用于存储已经被
方法区
在
方法区是一个线程共享的区域,它用于存储已被虚拟机加载的类信息、常量、静态变量。方法区是堆的逻辑组成部分,
此处补充一个在
Classloader 引用
运行时常量池
数值型常量
字段引用
方法引用
属性
字段数据
针对每个字段的信息
字段名
类型
修饰符
属性(Attribute)
方法数据
每个方法
方法名
返回值类型
参数类型(按顺序)
修饰符
属性
方法代码
每个方法
字节码
操作数栈大小
局部变量大小
局部变量表
异常表
每个异常处理器
开始点
结束点
异常处理代码的程序计数器(PC)偏移量
被捕获的异常类对应的常量池下标
运行时常量池
常量池中可以存储多种类型的数据:
- 数字型
- 字符串型
- 类引用型
- 域引用型
- 方法引用
示例代码如下:
Object foo = new Object();
写成字节码将是下面这样:
0: new #2 // Class java/lang/Object
1: dup
2: invokespecial #3 // Method java/ lang/Object "<init>"( ) V
package org.jvminternals;
public class SimpleClass {
public void sayHello() {
System.out.println("Hello");
}
}
生成的类文件常量池将是这个样子:
Constant pool:
#1 = Methodref #6.#17 // java/lang/Object."<init>":()V
#2 = Fieldref #18.#19 // java/lang/System.out:Ljava/io/PrintStream;
#3 = String #20 // "Hello"
#4 = Methodref #21.#22 // java/io/PrintStream.println:(Ljava/lang/String;)V
#5 = Class #23 // org/jvminternals/SimpleClass
#6 = Class #24 // java/lang/Object
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lorg/jvminternals/SimpleClass;
#14 = Utf8 sayHello
#15 = Utf8 SourceFile
#16 = Utf8 SimpleClass.java
#17 = NameAndType #7:#8 // "<init>":()V
#18 = Class #25 // java/lang/System
#19 = NameAndType #26:#27 // out:Ljava/io/PrintStream;
#20 = Utf8 Hello
#21 = Class #28 // java/io/PrintStream
#22 = NameAndType #29:#30 // println:(Ljava/lang/String;)V
#23 = Utf8 org/jvminternals/SimpleClass
#24 = Utf8 java/lang/Object
#25 = Utf8 java/lang/System
#26 = Utf8 out
#27 = Utf8 Ljava/io/PrintStream;
#28 = Utf8 java/io/PrintStream
#29 = Utf8 println
#30 = Utf8 (Ljava/lang/String;)V
这个常量池包含了下面的类型:
方法信息
异常表
异常表像这样存储每个异常处理信息:
- 起始点
(Start point) - 结束点
(End point) - 异常处理代码的
PC 偏移量 - 被捕获异常的常量池索引
如果一个方法有定义
当方法抛出异常时,
符号表
除了按类型来分的运行时常量池,
字符串表
("j" + "v" + "m").intern() == "jvm"
Hashtable<oop, Symbol>