java对象创建过程和JVM对象内存分配过程(转载)
Java对象创建的过程
Java中对象的创建就是在堆上分配内存空间的过程,此处说的对象创建仅限于new关键字创建的普通Java对象,不包括数组对象的创建
对象的创建大概分为以下几步:
1:检查类是否已经被加载;
2:为对象分配内存空间;
3:为分配的内存空间初始化零值(为对象字段设置零值);
4:对对象进行其他设置(设置对象头);
5:执行构造方法。
流程:
1.当虚拟机执行到new 关键字时,首先会去运行时常量池中查找该引用所指向的类有没有被虚拟机加载,如果没有被加载,那么会进行类的加载过程,如果已经被加载,那么进行下一步。
2.当类元信息被加载之后,我们就可以从常量池找到对应的类元信息,通过类元信息来确定类型和后面需要申请的内存大小。
3.对象的内存分配完成后,还需要将对象的内存空间都初始化为零值,这样能保证对象即使没有赋初值,也可以直接使用。(分配完内存后,需要对对象的字段进行零值初始化,对象头除外,零值初始化意思就是对对象的字段赋0值,或者null值,这也就解释了为什么这些字段在不需要进程初始化时候就能直接使用)
4.分配完内存空间,初始化零值之后,虚拟机还需要对对象进行其他必要的设置,设置的地方都在对象头中,包括这个对象所属的类,类的元数据信息,对象的hashcode,GC分代年龄等信息
5.然后执行对象内部生成的init方法,初始化成员变量值,同时执行搜集到的{}代码块逻辑,最后执行对象构造方法。执行对象的构造方法,这里做的操作才是程序员真正想做的操作,例如初始化其他对象啊等等操作,至此,对象创建成功。
以下引用自:
链接:
https://zhuanlan.zhihu.com/p/142614439
对象在内存的布局:
对象创建完成后在内存中保存了保存的信息包括对象头、实例数据及对齐填充三类信息。
对象头:对象头里主要包括几类信息,分别是锁状态标志、持有锁的线程ID、,GC分代年龄、对象HashCode,类元信息地址、数组长度,这里并没有对对象头里的每个信息都列出而是进行大致的分类,下面是对其中几类信息进行说明。
锁状态标志:对象的加锁状态分为无锁、偏向锁、轻量级锁、重量级锁几种标记。
持有锁的线程: 持有当前对象锁定的线程ID。
GC分代年龄: 对象每经过一次GC还存活下来了,GC年龄就加1。
类元信息地址: 可通过对象找到类元信息,用于定位对象类型。
数组长度: 当对象是数组类型的时候会记录数组的长度。
实例数据
对象实例数据才是对象的自身真正的数据,主要包括自身的成员变量信息,同时还包括实现的接口、父类的成员变量信息。
对齐填充
根据JVM规范对象申请的内存地址必须是8的倍数,换句话说对象在申请内存大小时候8字节的倍数,如果对象自身的信息大小没有达到申请的内存大小,那么这部分是对剩余部分进行填充。
JVM对象内存分配过程
java中创建一个对象时,对象到底是在哪里创建的?什么时候在堆上创建,什么时候在栈上创建?
这些问题,可以参考如下流程图。
原文章地址:
https://zhuanlan.zhihu.com/p/143743569
https://www.jianshu.com/p/bf5d20d8be19