类的整个生命周期:加载-链接(验证-准备-解析)-初始化-使用-结束
下图表示的是从new开始,类jvm操作的步骤。
大体思路就是,先去常量池中找有没有被编译过,如果发现已经编译过了。直接复制一份,将类的各种变量,常量都初始化一遍。然后调用<init>方法。注意:这个方法是合成的,会在类编译中讲解这里不详细说明。
如果没有,就开始进行类编译过程。类编译省略,会写详细的编译文档。
先说类的主要结构:对象头,数据存储方式,padding。
对象头比较复杂,先介绍数据存储方式:主要就是把相同字节的 数据放在一起 ,满足前面条件下父类的数据在子类之前。
padding:主要作用就是填充。有一些虚拟机对数据有位数要求的时候,如果数据没有达到位数,会用padding进行填充。
接下来是对象头,主要有两层,用字典的方式写一下全部的结构。
{对象头:
{自身运行时的数据(Mark Word):{
hash值(主要跟native本地方法有关,飘过):{},
GC分代(垃圾回收时使用):{},
锁状态标志:{},
线程持有的锁:{},
偏向线程id:{},
偏向时间戳:{}},
指针类型(保存找到对象实例的引用):{},
数组长度(如果是数组类型,保存长度):{}},
运行时数据:{},
padding:{},
}
这便是对象的基本结构信息。
戳重点:了解对象的结构,可以理解很多java的一些方法底层实现。例如锁的实现,里面用到了Mark Word。就是对这个的占用与等待去实现加锁的过程。
未完待续。。。。。。