java虚拟机之对象的创建

  在java这门面向对象的编程语言中,创建对象无时无刻不在被创建着。在Java中,仅仅用一个new关键字就能创建一个对象,那么在虚拟机中,对象创建的过程又是怎样呢?

  1.类加载检查

  当虚拟机接受到一条new指令时,虚拟机需要先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已被加载,解析和初始化过。若无,则先执行相应的类加载过程。

 2.分配内存

  在类加载检查通过后,虚拟机就会为新生对象分配内存。所需内存大小在类加载中就已经确认了。

3.初始化内存空间

 内存分配完成后,虚拟机将分配到的内存空间都初始化为零值(不包括对象头)。这一步操作保证了对象的实例字段在java代码中可以不赋初始值就能直接使用。

4.设置对象

接下来,虚拟机要对对象进行必要的设置,例如它是哪个类的实例,如何找到类的元数据类型,对象的哈希码,对象的GC分代年龄等。

在上面的工作完成后,从虚拟机的视觉来看,一个新的对象已经产生。

那么,我们对象分配内存机制又是怎样呢?

 1.假如java堆中的内存是绝对规整的,所有用过的和没用过的内存都整整齐齐放在两边,而中间是有一个指针作为分界点的指示器,那分配内存时只需要把这个指针向空闲那边移动一段与对象大小相等的距离即可,这种分配方式被称为“指针碰撞”。

2.若java堆的内存并不规整,而是空闲和已用内存相互交错。那虚拟机就要维护一个列表来记录哪些空间是可用的,在分配的时候在列表中找到一块足够大小的区域划分给这个对象,然后更新列表上的记录,这种分配方式被称为“空闲列表”。

选择哪种分配方式是由java堆是否规整来决定,而java堆是否规整由由所采用的垃圾收集器是否带压缩整理功能决定。

因此,在使用Serial,ParNew等带Compact过程的收集器,系统采用分配方式是指针碰撞;而使用CMS这种基于Mark-Sweep算法的收集器时,采用空闲列表方式。

猜你喜欢

转载自blog.csdn.net/ouyuansz/article/details/81053573