Java内存区域以及对象创建

概述

对于Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每一个new操作去写配对的delete/free代码,不容易出现内存泄漏问题。不过由于虚拟机的内存控制权限过大,导致程序员对内存错误的排除变得异常艰难,因此了解Java虚拟机对内存的使用方式变得非常重要。

运行时数据区域

Java虚拟机再运行时将内存划分为若干个不同的数据区域。这些区域各有用途以及创建和销毁时间,有的区域随虚拟机进程的启动而存在,有的区域则以来用户线程的启动、结束而建立和销毁。

  1. 程序计数器
    内存较小区域,可以看做当前线程执行的字节码行号指示器。某一时刻一个CPU(核)只能运行一条线程指令,该区域称为"线程的私有区域",各线程之间计数器互不影响,独立存储。
  2. Java虚拟机栈
    线程私有,与线程生命周期相同,每个方法执行的同事都会创建一个栈用于存放局部变量引用表(编译时所需空间确定)、操作数栈、动态链接、方法出口信息等。
  3. 本地方法栈
    本地方法栈功能与虚拟机栈发挥作用非常相似,区别仅在于虚拟机栈服务于虚拟机执行的Java方法,而本地方法栈则为虚拟机使用Native方法服务。
  4. Java堆
    所有线程共享区域,虚拟机启动时创建。唯一目的存放对象实例(数组对象),几乎所有实例对象分配于此。GC工作的主要场所,从回收角度可分为新生代和老生代。堆上内存可以物理上不连续,但必须逻辑上连续。
  5. 方法区
    所有线程共享区域,用于存储虚拟机加载的类信息、常量(基本数据类型以及部分基本数据类型封装类)、静态变量、及时编译器编译后的代码数据。
  6. 运行时常量池
    方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池存放。
  7. 直接内存
    直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。JDK1.4新加入了NIO(New Input/Output)类,引入一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native的方法直接分配堆外内存,然后通过存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。

虚拟机对象

  1. 对象的创建
    Java虚拟机程序运行过程中,无时无刻都有对象被创建。在语言层次中,创建对象(录入克隆、反序列化)通常仅仅是一个new关键字而已。
    虚拟机再遇到一条new指令时,首先根据指令参数能否在常量池中定位这个类的符号引用,并检查这个符号引用的类是否已被加载、解析和初始化过。如果未加载则必须先进行加载。
    类加载后,虚拟机未新对象分配内存(内存大小分配时已确定)。
    虚拟机内存管理方式:
    ①绝对规整:已使用内存位于内存区域的一侧,未使用内存区域位于另一侧,中间使用指针进行标记,内存的分配将导致指针的移动
    ②相对规整:已使用内存与未使用内存相互交错,虚拟机需要维护内存空闲表对内存进行管理。表中记录相应内存块首地址以及其大小
    内存分配安全:并发情况下可能导致内存分配冲突
    ①对分配内存空间的动作进行同步,保证更新操作的原子性
    ②使用本地线程分配缓冲机制,位不同线程分配不同的缓冲区,对缓冲区进行监控,并适时扩充
    在虚拟机为对象分配好内存之后,虚拟机需要将新分配的内存区域进行清零(这就是一些基本数据类型可以进行未初始化访问的原因)
    清零后,虚拟机会为对象执行init方法,此时对象的创建真正完成
  2. 对象的内存布局
    对象的内存区域可以分为三块:对象头、实例数据、对齐填充
    ①对象头包含两部分信息:第一部分用于存储运行时数据(哈希吗、GC年龄、锁状态标志等);第二部分为类型指针,即对象指向它的类元数据的指针(从数组的元数据中无法确定数组长度大小,但可以通过普通Java对象的元数据信息确定Java对象的大小)。
    ②实例数据:对象真正存储的有效信息,也是在程序中所定义的各种类型的字段内容(父类继承的以及子类中定义的)。
    ③对齐填充:不是必然存在的,也没有特殊意义。
  3. 对象的访问定位
    Java的对象引用(reference)位于栈中,具体对象位于堆中。为了使用对象,则需要建立引用与对象的关联,目前关联方式有:句柄关联、直接指针关联
    ①句柄关联:引用(位于栈中,存放稳定句柄地址)、句柄(位于堆中,存放不稳定对象地址)、对象(位于堆中,由于GC机制的存在,地址变动频繁)
    ②直接指针关联:定位速度快,节省了一次指针定位的时间开销,是目前SunHotSpot的对象访问方式
发布了28 篇原创文章 · 获赞 3 · 访问量 1603

猜你喜欢

转载自blog.csdn.net/qq_43044875/article/details/103972160