HotSpot是最新的虚拟机,替代了JIT,提高Java的运行性能。Java原先是将源代码编译为字节码在虚拟机运行,HotSpot将常用的部分代码编译为本地代码。
对象创建过程 类加载
分配内存
初始化
设置对象头
执行init
对象的内存布局
| 对象头 | 记录一个对象的实例名字、ID和实例状态
普通对象占用 8 bytes,数组占用 12 bytes (8 bytes 的普通对象头 + 4 bytes 的数组长度)
2.类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象的哪个实例。
基本类型
引用类型
对齐填充物
计算 User 对象占用空间大小?
User 对象有两个属性,一个 int 类型的 id 占用 4 bytes,一个引用类型的 name 占用 4bytes,在加上 8 bytes 的对象头,正好是 16 bytes
Java程序需要通过JVM栈上的引用访问堆中的具体实例
方法 概念 优点句柄 堆中划分一块内存作为句柄池,引用中存放对象的句柄地址,句柄池中存放对象实例的指针以及对象类信息的指针。
引用中存放的是稳定的句柄地址,当对象移动时,引用本身不需要修改
直接指针 引用中存放的是对象的地址,对象的类信息指针也存在实例中。
如果使用直接指针访问,那么Java堆对象的布局中就必须考虑如何放置访问类型数据的相关信息,而reference中存储的直接就是对象地址。
速度更快,节省了一次指针定位的时间开销 (HotSpot采用该方式)
二、类加载机制
虚拟机将编译好的字节码文件加载进JVM内存,也就是运行时数据区,并对数据进行校验、解析、初始化,然后由执行引擎将字节码指令转为底层系统指令。类加载器只负责加载,不负责运行。
Java中的所有类,都是有误类加载器加载到JVM然后运行的,类加载器本身也是一个类,负责将class文件从硬盘加载到内存。
类加载是动态的,不会一次性将所有的类都加载,而是对于程序运行必须的类会先加载,其他类在使用的时候才进行加载。这样做可以节省内存开销。
概念:通过类的全限定类名获取该类的二进制字节流。
启动类加载器BootStrap 用于加载java核心类库,lib下的jar包的类,提供初始化环境,比如Object、String扩展类加载器Extension 用于加载Java的扩展库,JavaX包下的类,比如swing、awt等
应用程序类加载器Application 用于加载应用类路径classpath下的类,比如自己定义的Hello.class类
用户自定义类加载器 通过继承java.lang.ClassLoader实现
类加载过程 加载 类加载器加载class文件到内存
验证 验证class文件的正确性,class文件的开头有特定的标识 --> cafe babe
准备 给类中的静态变量分配内存空间并且初始默认值
解析 将类常量池中的符号引用解析为直接引用
初始化 初始化阶段就是类的构造器方法的执行过程,该方法是由编译器自动收集类中的所以类变量的赋值动作以及静态代码块中的语句合成的,其中编译器收集的顺序是由语句在源文件中出现的顺序决定的。