new的流程:
1. 检查常量池中是否又对应new的该类的符号引用,如果没有会报错not found class type;
2. 如果有就判断是否已经通过classloader加载,如果没有加载会进行加载;
3. 然后在堆上新生代的eden区进行分配内存,eden区会根据当前JVM的线程数将划分成很多的TLAB(Thread Local Allocation Buffer)区,每个线程一个,这个TLAB是为了避免多线程下对eden区内存并发操作带来的线程不安全的问题;
4. 在调用类构造函数之前,首先会对对象头进行初始化,初始化内容有(hash码,对象锁信息,GC分代年龄等),还有就是需要初始化所有的成员field为默认值;
5. 执行实例初始化块,然后是构造函数;
6. 返回堆上面该对象指针(该指针有两个,一个指向堆上数据实际地址,一个指向方法区该对象所有的数据类型信息的存储地址),该指针存储在堆上面的一个指针池(也叫句柄池)中;
7. 最后在方法栈上分配一个reference数据类型的变量来存储指向该对象在指针池的内存地址;new以后返回的变量就是这个refernce数据类型。
这样多了一层指针池,obj数据在分代算法的时候不停变动内存地址,屏蔽了Java方法栈中reference的变化,让变化停留在指针池中。