本次不以实际的面试题实例,我们讲解对象的创建过程,和常见问题,对象的结构,对象的访问,这些问题会在经常隐藏在面试题中。
问题:简单描述Java中的对象创建过程
解析:
分为3个部分讲解,分别是对象创建过程,对象的结构,对象的访问
对象的创建过程
这里我们线介绍使用new关键字来创建对象的过程
- 步骤如下:
- 根据new的参数在常量池中定位一个类的符号引用。
- 如果没有找到这个符号引用,说明类还没有被加载,则进行类的加载解析和初始化。
- 虚拟机为对象分配内存,位于堆中。
- 将分配的内存初始化为零值,引用类型初始化为null(不包括对象头)
- 调用对象的init()方法(实际是代码块或者构造方法)
一般我们可以看到的信息就是在使用构造方法初始化的时候,其他的都在虚拟机中执行。
- 在初始化的过程中会被提到的问题
- 给对象分配内存的问题,常用的内存分配机制下面两种
指针碰撞
空闲列表
具体使用那种由垃圾回收器决定,当垃圾回收器在回收的时候将内存进行
整理,就使用指针碰撞。
- 分配内存的时候线程安全型问题
在多线程的情况下,在使用空闲列表分配内存的时候,如果在表中已经为上一个对象创建了内存,但是表的信息没有更新已经分配的数据时候,下一个线程 进来,导致内存分配出错
解决方法:
- 我们常规的方法加锁,会影响效率。
- 使用本地线程缓冲,在堆中分配出来多个小的内存区域,针对单个线程
进行执行。
- 初始化对象的过程问题
- 执行构造方法时候出现的问题
对象的结构
对象的结构可以分为下面的三种
- Header
自身运行时候的数据(哈希值,GC分代年龄)垃圾回收的算法
类型指针 - InstanceDate
真正存储的有效信息(继承的和自身的)
相同宽度的字段会分配到一起
父类的数据会在子类的前面 - Padding
数据填充
对象的访问定位
引用只是指向对象的一个地址,还需要定位到方法区的对象类型的信息
- 使用句柄
首先定位到句柄池,在执行一个对象的地址。好处不需要更改引用 - 使用直接指针
直接执行对象的地址,访问速度比较快(HotSpot)