在上一篇我们知道了Jvm的内存划分,这一篇我们来具体分析一下,当我们用new关键字创建一个新对象时,Jvm都做了哪些工作。当虚拟机执行到new指令时,发现它是关键字,于是会检查这个指令参数是否能在常量池中找到相关的引用,并检查这个引用所代表的类是否被加载、解析和初始化过。如果没有被加载,则先执行类的加载过程。当类加载成功后,虚拟机就会为新创建的对象分配内存。分配内存无非就是在Java堆上划出一部分区域来作为新对象的存储空间。但在实际的处理时是比较麻烦的。例如怎么找到空闲的内存,如何划分固定大小内存。我们知道Java虚拟机规范中所说虚拟机中的堆内存可以是连续的也可以是不连续的。所以虚拟机在为对象分配新内存时,就要根据这两种不同的方式来采取不同的实现。这两种方式分别叫作:指针碰撞和空闲列表。正面我们分别看一下它们具体的实现方式。
由于不同的虚拟机所采用的内存分配方式是不同的,所以上述主要说明两种分配内存的方式,虚拟机到底采用哪种方式由不同虚拟机的堆自行决定。
上述的过程只是给对象分配了相关的内存空间,但对象还是空的,内存数据要怎么保存对象的信息呢?在虚拟机中对象在内存中存储主要分3个区域:
对象现在已经创建完了,但它是存储在堆上的,为了方便我们操作堆中的对象,Java是通过栈上的引用数据来操作堆上的具体对象的。这个引用是使用直接指针访问的。堆中要存储这个指针的相关信息,而引用存储的就是该对象的内存地址。
以上就是在创建一个新对象时Jvm对内存的主要操作。因为不同的虚拟机可能有不同的处理逻辑,上述中所描述的虚拟机都指的是Sun HotSpot虚拟机。