转载:https://blog.csdn.net/Time_Travel/article/details/78649137
以Object obj = new Object();的过程进行分析这一行代码的背后,JVM都做了些什么。
一、检查常量池中是否存在该类的符号引用,如果没有,则先加载该类,并解析和初始化
二、为对象分配内存
内存大小在类加载的时候已经确定大小,如下图:
分配内存过程中需要考虑的问题:
2.1内存是否规整
① 假设Java 堆中内存是连续规整的,也就是说Heap中一侧是已经使用过的内存空间,而另一侧是空闲空间,则此时使用指针指向起始空闲内存,当需要分配新的空间时,只需要将指针向后移动制定空间大小位置即可完成内存的分配,这种分配方式称为“指针碰撞”(Bump the Pointer)
② 假设内存并不是连续规整的,空闲和使用的相互交错,则此时JVM就需要记录哪些内存块石可用的,分配时,分配足够大的空间给对象实例,同事更新记录列表。这种方式称为“空闲列表”(Free List)
而是采用Bump the Pointer的方式还是Free List的方式由JVM Heap是否规整决定,而Heap的规整与否又由所采用的垃圾收集器是否带有亚索整理的功能决定。使用Serial、ParNew等带有Compact过程的收集器时则采用指针碰撞,而使用CMS这种给予Mark Sweep算法收集器时,采用Free List方式。
2.2对象的创建十分频繁,如何解决并发带来的不安全问题
方法一、同步,即对分配内存空间的动作进行同步处理——-采用CAS加上失败重试的方式保证更新操作的原子性。
方法二、TLAB,把内存分配的动作按照线程划分在不同的空间上进行,即每个线程预先分配一小块内存,这种方式称为本地线程分配缓冲(Thread Local Allocation Buffer),这种方式只需要在分配新的TLAB时进行同步锁定
是否采用TLAB方式可以通过使用-XX:+/-UserTLAB决定
三、内存分配完成后的必要设置
如:
该实例为那一个类的实例
类的元数据信息
对象的哈希码
对象的GC分代信息
等等
以上信息位于对象的头信息中(Object Header),除此之外,对象的其他字段都还是0,至此一个新的对象已经产生,但是尚未进行初始化。
四、对象的初始化,执行init方法
至此,一个对象完成创建过程
---------------------