JVM虚拟机运行时数据区(每个区都存储什么信息)
JAVA7和JAVA8的运行时数据区
JAVA7:
虚拟机栈/本地方法栈:线程私有,由栈帧组成,每个栈帧由局部变量表,动态链接,和方法出口,操作数组成
其中局部变量表负责存储当前调用的方法内的基本变量和对象引用(包括形参,方法内参数)
动态链接相当于方法引用
方法区(线程共享):存储类的元信息(类的版本,字段,方法,接口),静态变量和常量池(常量和符号引用),class对象存在堆中
对象的两种访问形式
对象的实例化
在准备实例化一个类的对象前,首先准备实例化该类的父类,如果该类的父类还有父类,那么准备实例化该类的父类的父类,依次递归直到递归到Object类。此时,首先实例化Object类,再依次对以下各类进行实例化,直到完成对目标类的实例化。具体而言,在实例化每个类时,都遵循如下顺序:先依次执行实例变量初始化和实例代码块初始化,再执行构造函数初始化。也就是说,编译器会将实例变量初始化和实例代码块初始化相关代码放到类的构造函数中去,并且这些代码会被放在对超类构造函数的调用语句之后,构造函数本身的代码之前。
类的创建:
转载自:https://www.cnblogs.com/chenyangyao/p/5296807.html
类的加载
类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class对象,用来封装类在方法区内的数据结构
分为以下几个步骤
加载 :
(1)通过一个类的全限定名来获取其定义的二进制字节流
(2)将这个字节流所代表的的静态存储结构转化为方法区的运行时数据结构
(3)在堆中生成一个代表这个类的Class对象,作为方法区中这些数据的访问入口。
链接
校验 :校验class文件的正确性
准备:为静态变量分配内存空间和初始值(这里指各数据类型的默认值)
解析 :符号引用转直接引用
初始化:为內的静态变量加载赋予正确的初始值
类加载器
Bootstrap ClassLoader:加载JRE_HOME%\lib ,可通过启动JVM时指定-Xbootclasspath和路径来改变Bootstrap ClassLoader的加载目录
Extention ClassLoader:加载JRE_HOME%\lib\ext目录,可通过-D java.ext.dirs指定加载目录
Appclass Loader:也称为SystemAppClass。 加载当前应用的classpath的所有类
双亲委派:父级加载器加载过的类,子加载器不再加载
对象的内存布局
分三块:
1、对象头
1.1、对象的运行时数据:哈希码、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等,32 位虚拟机占 32 bit,64 位虚拟机占 64 bit。官方称为 ‘Mark Word’
1.2、对象的类型信息:对象指向它的类的元数据指针
2、实例数据
3、对其填充:不是必然需要,主要是占位,保证对象大小是某个字节的整数倍