10.21Spring解决循环依赖的三级缓存:10.28对象创建过程1)检查类是否已经加载2)为对象分配内存空间3)为分配的内存空间初始化零值4)为对象做其他设置(设置对象头)5)执行构造方法流程:1、虚拟机在执行new关键字时,会先去运行时常量池检查引用指向的类是否存在已经被虚拟机加载了,如果没有加载,那么就会进行类加载过程,如果已经加载了,那么就会进行下一步。2.加载完分类器信息后,我们可以从常量池中找到对应的分类器信息,通过分类器信息来判断类型和后面需要申请的内存大小。3、对象的内存分配完成后,需要将对象的内存空间初始化为零值,以保证即使不分配初始值也可以直接使用对象。(分配内存后,需要对对象的字段进行零值初始化,对象头除外。零值初始化是指给对象的字段赋值0或null,这就解释了为什么这些字段做不需要进程初始化。4.分配内存空间和初始化零值后,虚拟机需要对对象进行其他必要的设置,这些设置都在对象头中,包括对象所属的类和类的元数据信息,对象hashcode,GC分代年龄等信息5.然后执行对象内部生成的init方法,初始化成员变量值,同时执行收集到的{}代码块逻辑,最后执行对象的构造方法,执行对象的构造方法,这里执行的操作是程序员真正想做的操作,比如初始化其他对象等等。至此,对象创建成功。DCL(DoubleCheckLock)单例模式是否需要volatile?是的,volatile在DCL单例中不使用其线程可见性,但禁止指令重新排序。详情:https://blog.csdn.net/qq_2681...对象在内存中的存储布局https://blog.csdn.net/ljc1026...对象头具体包括哪些内容?mark:用来存放对象本身的运行时数据,比如hashcode、GCgenerationage、lockstatusflag、threadpoollocks等,都是4-byte(32-bit)或者8-byte(64-bit)类型pointers:即对象指向其类Metadata(保存在方法区)的指针,虚拟机通过这个指针来判断对象属于哪个类。为4字节(32位)或8字节(64位,但默认启用压缩,即4个字)数组长度(仅适用于数组对象):使用4字节的int记录数组长度。如何在java中定位对象。实例对象的内存地址,那么为什么方法1使用句柄存在呢?答:好处是无论实例对象在堆中的地址发生变化还是被垃圾回收,栈中的引用都不会改变。改变的是堆中句柄池保存的内存地址,栈中的引用不会改变。需要修改。使用模式2直接指针有什么好处?答:引用直接指向堆内存中的对象地址。与使用句柄相比,减少了一次寻址过程,减少了一次性能开销。因为对象的访问和定位频率很高,节省性能,速度快。那么HotspotVM采用了什么样的对象访问和定位方式呢?答:HotspotVM使用方法2直接指针定位方法如何分配对象https://juejin.cn/post/684490...Objecto=newObject()占用多少字节Mark:8Typepointer:4PaddingAlignment:4共16字节为什么hotspot不用C++对象来表示Java对象函数表。Java的特点就是万物皆对象。如果每个对象都维护一个虚函数表,那么内存开销会非常大。JVM对此进行了优化。虚函数表不再按每个对象维护,而是按类类型维护。这种类型的所有对象共享一个虚函数表。HotSpot使用Oop-Klass模型来表示Java对象,其中Klass对应Java对象的类型(Class),Oop对应Java对象的实例(Instance)。Oop是一个继承体系,其中oop是体系中的最高父类,其存储结构可分为对象头和对象体。对象头存储了对象的一些元数据,对象体存储了具体的成员属性。值得注意的是,如果是普通对象类型,oop只存储成员属性的地址。类对象是在堆中还是在方法区?类对象存放在堆区,而不是方法区。很多人在这一点上容易犯错误。类的元数据(元数据不是类的Class对象!Class对象是加载的最终产物,类的方法代码、变量名、方法名、访问权限、返回值等都在方法区)。方法区。11.4g1:部分修复gms中的内存碎片,可预测的暂停时间11.1211.15
