jvm运行时数据区域解析
刘望舒的BLOG
虚拟机的内存模型
一、内存模型
image.png1.程序计数器: 确定程序指令执行顺序的,是唯一一块不会发生内存溢出的区域
它是线程私有的,负责记录当前线程空间字节码执行的行号(当线程切换后,由于有程序计数器来记录执行的地方,所以能够正确恢复到指定的位置)
2. Java虚拟机栈
**它也是线程私有的,负责存储方法内的局部变量,方法出口等。每执行一个方法都相当于压如一个栈帧,方法执行完比后这个栈帧从Java虚拟机栈中弹出。
3.本地方法区
负责管理虚拟机用到的 C 的方法。
4.堆内存区域
Java堆是一块被所有线程共享的区域,用来存放对象的实例。它不需要物理上连续,只需要逻辑上连续就可以。
5.方法区
方法区是被所有线程共享的的内存区域,用来存放已经被Java虚拟机加载的类的结构信息:运行时常量池,字段,方法信息,静态变量等数据。
当虚拟机读入一个 class 文件后,会把这个 class 文件的信息存储到方法区中.
- 这个类型的全限定名(如全限定名java.lang.Object)
- 这个类型的直接超类的全限定名
- 这个类型是类类型还是接口类型
- 这个类型的访问修饰符(public, abstract, final的某个子集)
- 任何直接超接口的全限定名的有序列表
- 该类型的常量池(一个有序集合,包括直接常量[string, integer和floating point常量]和对其它类型、字段和方法的符号引用)
- 字段信息(字段名、类型、修饰符)
- 方法信息(方法名、返回类型、参数数量和类型、修饰符)
- 除了常量以外的所有类(静态)变量
- 指向ClassLoader类的引用(每个类型被装载时,虚拟机必须跟踪它是由启动类装载器还是由用户自定义类装载器装载的)
- 指向Class类的引用(对于每一个被装载的类型,虚拟机相应地为它创建一个java.lang.Class类的实例。比如你有一个到java.lang.Integer类的对象的引用,那么只需要调用Integer对象引用的getClass()方法,就可以得到表示java.lang.Integer类的Class对象)
class文件的内容
ClassFile {
u4 magic; //魔数:0xCAFEBABE,用来判断是否是Java class文件
u2 minor_version; //次版本号
u2 major_version; //主版本号
u2 constant_pool_count; //常量池大小
cp_info constant_pool[constant_pool_count-1]; //常量池
u2 access_flags; //类和接口层次的访问标志(通过|运算得到)
u2 this_class; //类索引(指向常量池中的类常量)
u2 super_class; //父类索引(指向常量池中的类常量)
u2 interfaces_count; //接口索引计数器
u2 interfaces[interfaces_count]; //接口索引集合
u2 fields_count; //字段数量计数器
field_info fields[fields_count]; //字段表集合
u2 methods_count; //方法数量计数器
method_info methods[methods_count]; //方法表集合
u2 attributes_count; //属性个数
attribute_info attributes[attributes_count]; //属性表
}
网友评论