返回

Java对象的内存模型及“垃圾收集”机制探秘

后端

《深入Java(五)》——对象的内存模型、实体与引用以及“垃圾收集”机制

在开始讲讲Java当中对象的内存模型之前,先摆出创建一个对象(也叫实例化对象)所必须经历的三个步骤。现在假设有一个Person类。

  1. 首先给Person类创建一个Class对象(也叫类对象)。Person类的.class文件存储着用来Person类的元数据。在Java中,类对象存储在方法区 (Method Area)之中。方法区是Java虚拟机所划分出来的内存区域,除了用于存储类信息外,还用于存储常量、静态变量以及即时编译器编译后的代码等数据。

  2. 接下来创建一个Person对象的实例。在这个步骤中,会分配一块内存用于存放这个对象的成员变量。这块内存区域叫作堆内存 (Heap)。堆内存是Java虚拟机所划分出来的用于存放对象实例的内存区域。

  3. 将创建好的Person对象实例的地址值存入栈(Stack)中的一个局部变量里。栈是Java虚拟机所划分出来的用于存放线程私有数据的内存区域。

  4. 当堆内存当中不再有对该对象实例的任何引用,则“垃圾收集”机制就会回收该对象的所占内存空间。

Java对象的内存模型

Java对象的内存模型规定了对象在内存中的布局,包括对象头、实例数据和对齐填充。

1. 对象头

对象头包括以下信息:

  • Mark Word :用于存储对象的状态信息,包括对象的哈希码、GC标记位、锁标志位、偏向锁标志位等。
  • Klass Pointer :指向对象所属的类对象的指针。
  • Array Length :如果是数组对象,则存储数组的长度。

2. 实例数据

实例数据存储着对象的状态信息,包括对象的成员变量。

3. 对齐填充

为了确保对象在内存中的对齐,有时需要在对象头和实例数据之间添加对齐填充字节。

实体与引用

在Java中,对象是实体,引用是指向实体的指针。

实体

实体是指实际存在于内存中的对象。每个实体都有一个唯一的地址。

引用

引用是指向实体的指针。引用是一个32位的内存地址,指向实体在内存中的地址。

垃圾收集机制

垃圾收集机制是Java虚拟机的一项重要功能,用于回收不再被引用的对象所占用的内存空间。

垃圾收集器

垃圾收集器是负责执行垃圾收集过程的程序。Java虚拟机提供了多种不同的垃圾收集器,包括:

  • Serial GC :单线程垃圾收集器,适用于小型应用程序。
  • Parallel GC :多线程垃圾收集器,适用于中型应用程序。
  • Concurrent Mark Sweep GC :并发标记清除垃圾收集器,适用于大型应用程序。
  • G1 GC :基于分代收集的垃圾收集器,适用于大型应用程序。

内存回收策略

垃圾收集器使用不同的内存回收策略来回收不再被引用的对象。常见的内存回收策略包括:

  • 标记-清除算法 :垃圾收集器首先标记不再被引用的对象,然后清除这些对象所占用的内存空间。
  • 标记-压缩算法 :垃圾收集器首先标记不再被引用的对象,然后将未被标记的对象压缩到一起,从而释放出连续的内存空间。
  • 分代收集算法 :垃圾收集器将堆内存划分为不同的区域,每个区域都有不同的垃圾收集策略。

内存管理

内存管理是Java虚拟机的一项重要功能,用于管理Java应用程序的内存使用情况。内存管理包括以下几个方面:

  • 内存分配 :当创建一个新的对象时,Java虚拟机需要为这个对象分配内存空间。
  • 内存回收 :当一个对象不再被引用时,Java虚拟机需要回收这个对象所占用的内存空间。
  • 内存整理 :当内存中出现碎片时,Java虚拟机需要对内存进行整理,以便为新的对象分配连续的内存空间。

性能优化

通过对Java对象的内存模型、实体与引用以及垃圾收集机制进行优化,可以提高Java应用程序的性能。常见的性能优化技术包括:

  • 减少对象创建 :尽量减少创建新的对象的数量。
  • 复用对象 :尽量复用现有的对象。
  • 避免内存泄漏 :确保不再被引用的对象能够被垃圾收集器回收。
  • 选择合适的垃圾收集器 :根据应用程序的具体情况选择合适的垃圾收集器。
  • 合理配置内存参数 :合理配置Java虚拟机的内存参数,例如堆内存大小、新生代内存大小、老年代内存大小等。