1.创建对象的方式
①new。②Class的newInstance()。③Contructor的newInstance(Xxx)。④使用clone()。⑤使用反序列化。⑥Object第三方Objenesis。
2.创建对象的步骤
①判断对象对应的类是否被加载、链接、初始化。
②为对象分配内存,如果内存规整,使用指针碰撞,如果内存不规整,虚拟机需要维护一个列表,空间列表分配
③处理并非安全问题,采用CAS配上失败重试保证更新的原子性,每个线程预先分配一块TLAB。
④初始化分配到空间,所有属性设置默认值,保证对象实例字段在不赋值时可以直接使用
⑤设置对象的对象头。
⑥执行init方法进行初始化。
3.对象的内存分布
4.对象访问定位
创建对象的目的就是为了使用它,JVM是如何通过栈帧中的对象引用访问到内存内部的对象实例呢,是通过栈帧上reference访问。
对象访问方式主要又两种:句柄访问,直接指针(HotSpot)采用。
上面是两种访问方式的示意图。
5.直接内存概述
它不是虚拟机与性能时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。直接内存是在Java堆外、直接向系统中申请内存区间。来源NIO,通过在堆中的DirectByteBuffer操作Native内存,通常,访问内存的速度会优于Java堆。读写性能高。因此处于性能考虑,读写频繁的场合可能会考虑使用直接内存,Java的NIO允许Java程序使用直接内存,用于数据缓冲区 。
它也可能导致OutOfMemoryError异常,由于直接内存在Java堆外,因此它的大小不会直接受限于-Xmx指定的最大堆大小,但是系统内存是有限的,Java堆和直接内存的总和依然受限于操作系统能给出的最大内存。
缺点:分配回收成本较高,不受JVM内存回收管理。
直接内存大小可以通过MaxDirectMemorySize设置,如果不指定,默认与堆最大值-Xmx参数值一致。