分别从jvm层次和程序视角来看:

jvm 层次来看的话,当 new 对象的时候,jvm先会到常量池中查找对象

jvm层次:

           jvm虚拟机遇到一条new指令的时候,首先会到常量池中去查找当前的指令的参数是否已经加载解析过,如果没有就要进行类的加载(类加载单独在说),

           如果已经加载,这个时候就会到堆内存中给当前的类分配内存,类的内存大小在类加载完成之后就可以确定。如果说堆内存是绝对规则的,已经使用的内存和

           未使用的内存中间就可以使用指针进行区分,只要指针向未使用的内存区域移动指定的类的大小的内存空间即可。如果说堆的内存不是规则,已使用的和未使用的内存交

           互存在,这个时候就没法使用指针碰撞了,必须维护一个堆内存的使用列表,记录那些是使用的那些是未使用的,在分配的内存的时候给新的对象分配一个足够大的

           未使用的内存,这种方式叫做‘空闲列表’。

           对于jvm使用哪种分配方式,就要看堆内存的空间是否完整,堆内存是否规则,就要看jvm使用了哪种垃圾回收器(垃圾回收器是否带有压缩整理功能)。例如使用Serial、

           ParNew等带Compact过程的收集器,使用的就是指针碰撞,而使用CMS这种基于Mark-Sweep算法的收集器,就是使用空闲列表。

           对象的创建对应jvm来说也是非常频繁的,即使是修改一个指针的位置,在高并发的情况下也是不安全的,有可能在在给A分配内存,指针还没有移动,

           JVM又使用了原先的指针给B分配了这块内存。解决这个问题有两种方案, 一种是对分配内存的动作进行同步操作,实际上jvm采用的是CAS配上失败重试。另一种方式就是

           按照线程在不同的空间进行,既每个线程预先在堆中分配一块内存,也就是叫TLAB(本地线程分配缓存),那个线程需要分配内存,就是使用哪个对象的TLAB,除非线程的TLAB不足,

           才会去同步申请内存,是否使用TLAB,可以通过使用--XX:+/-UseTLAB参数来设定。

           接下来就是对对象进行必要的设置,例如对象头的设置(这个对象时哪个类的实例,怎么才能找到这个类的元数据信息,对象的哈希码等)

           以上完成之后,jvm层面的来说,一个新的对象已经创建成功,对应程序而言,对象才创建才刚刚开始。

程序方面的对象创建:

            程序方面就是按照个人的设置进行初始化对象,以图表的展示初始化的一个过程

       

       运行结果: