建立一个对象一般是须要new关键字,安全
- 当虚拟机遇到一条new指令时,
- 首先检查这个指令的参数是否在常量池中定位到一个类的符号引用,
- 而且检查这个符号引用表明的类是否已被加载、解析和初始化过。
- 若是是
- 类加载检查经过后,
- 虚拟机将为新生对象分配内存。
- 为对象分配空间的任务等同于把一块肯定大小的内存从Java堆中划分出来。
分配的方式有两种:线程
- 一种叫 指针碰撞 ,
- 假设Java堆中内存是绝对规整的,
- 用过的和空闲的内存各在一边,
- 中间放着一个指针做为分界点的指示器,
- 分配内存就是把那个指针向空闲空间的那边挪动一段与对象大小相等的距离。
- 另外一种叫 空闲列表 :
- 若是Java堆中的内存不是规整的,
- 虚拟机就须要维护一个列表,
- 在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录。
- 采用哪一种分配方式是由*Java堆是否规整决定的,
- 而Java堆是否规整是由所采用的垃圾收集器是否带有压缩整理功能决定的。
须要考虑的问题就是对象建立时的线程安全问题,指针
- 有两种解决方案:
- 一是对分配内存空间的动做进行同步处理;
- 另外一种是吧内存分配的动做按照线程划分在不 同的空间之中进行,
- 即每一个线程在Java堆中预先分配一小块内存(TLAB),
- 哪一个线程要分配内存就在哪一个线程的TLAB上分配,
- 只有TLAB用完并分配 新的TLAB时才须要同步锁定。
内存分配完成后,虚拟机须要将分配到的内存空间初始化为零值。对象
- 这一步操做保证了对象的实例字段在Java代码中能够不赋初始值就能够直接使用。