对象创建的步骤
    1、判断对象对应的类是否加载,连接,初始化?虚拟机遇到一条new指令,首先检查这个指令的参数能否在Metaspace的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载,解析和初始化了(即判断类元信息是否存在?)如果没有,那么在双亲委派模式下,使用当前类加载器以ClassLoader+包名+类名为key的方式进行查找对应的class文件,如果没有找到,则会抛出ClassNotFoundException异常,如果找到,则进行类加载,并生成相对应的Class类对象
    2、为对象分配内存:如果内存时规整的,则以指针碰撞的方式进行分配;如果内存不规整,虚拟机需要维护一个列表,利用空闲列表分配;选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾回收器是否带有压缩整理功能决定
    3、处理并发安全问题:采用CAS配上失败重试保证更新的原子性,每一个线程预先分配一块TLAB
    4、初始化分配到的空间:所有属性设置默认值,保证对象实例字段在不进行赋值的情况下能够直接使用
    5、设置对象的对象头
    6、执行init()方法进行初始化

    直接内存(Direct Memory)

    直接内存概述
    1.不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域
    2.直接内存时Java堆外的,直接向系统申请的内存区间
    3.来源于NIO,通过存在堆中的DirectByteBuffer操作Native内存
    4.通常,访问直接内存的速度会优于Java堆,即读写性能高
    因此,处于性能的考虑,读写频繁地场合可能会考虑使用直接内存
    Java的NIO库允许Java程序使用直接内存,用于数据缓冲区

    对比直接缓冲区和非直接缓冲区读写文件的过程:
    image.png

    image.png
    注意:
    1.直接内存也可能导致OutOfMemoryError异常;
    2.由于直接内存在Java堆外,因此它的大小直接受到-Xmx指定的最大堆大小,但是系统内存是有限的,Java堆和直接内存的总和依然受限于操作系统能给出的最大内存.
    3.直接内存的缺点
    分配回收成本较高
    不受JVM内存回收管理
    4.直接内存大小可以通过MaxDirectMemorySize设置
    5.如果不指定,默认与堆的最大值-Xmx参数值一致