JVM-对象的创建

需要提前知道的东西:

  1. java堆里存放的是对象,这个对象是个引用,指向了方法区(建议复习一下JVM各个区域是干嘛的,有什么用)
  2. 方法区是什么?
    • 存放的是类似元数据信息方面的信息,比如:类信息、常亮、静态变量
  3. 常量池是属于方法区的

对象的创建

在平常写代码里,我们都是通过new这个关键字来创建一个对象,但是在虚拟机里,其实是一个挺复杂的过程:

1. 检查这个指令参数是否能够在常量池中定位到一个类的符号引用

  • 这是用来判断这个类是否已经被加载了,也就是说,一个类被创建之后,要执行类加载才能把类加载到JVM中
  • 如果类加载了,皆大欢喜,如果没有被加载,则需要重新执行一次类加载的过程 (暂时不用了解类加载过程,知道即可)
  • 打个比方:我们准备了一间屋子(虚拟机)让母鸡(类)来下蛋(对象),只有母鸡走进了这屋子才能下蛋,如果没进来,我们就把它赶进来(类加载)

2. 类加载完成后,需要划分内存空间(堆)

  • 也就是说需要把没有利用的内存空间划分出来用,但是这个空闲的内存空间是怎么管理的?学过os的应该很容易理解
  • 第一种方法:空闲区域和已分配区域是连续的(也就是所谓的规整的),也就是分开的,来张图可能更形象,每次分配只需要移动那个分割线(指针)就行,这种就叫"指针碰撞"
  • 第二种方法:空闲区域散落在各处(不规整),将空闲区域记录在一张表中,这个表叫做"空闲列表",下图大概是这个意思
  • 第一种和第二种方法的区别在于:如果有一种机制,在分配后能够管理这两块区域,使之空闲的在一起,不空闲的在一起,这也就叫做"压缩整理",有压缩整理的话就是第一种方法,没有的话就是第二种方法

3. 先看一个对象示意图,可以看到对象被逻辑上分为两个部分(不用知道为什么),其中一个就是对象头

  • 先初始化内存内容为0,因为这块内容上一次使用后数据可能还没释放,为了安全起见则对这片内存进行初始化
  • 然后设置对象头信息,包含:这是哪个类的实例、hash码是多少、是否启用偏向锁等等

4. 在new了之后,一般紧接着会执行<init>方法,也就是按照程序员的意愿去初始化数据,例如我们在一个类里写了一个成员,private int a = 1,也算作是我们自己的意愿值


如有错误,虚心接受指正,感谢!

原文地址:https://www.cnblogs.com/ccxka/p/13222392.html