返回

揭秘Java虚拟机内存区域与垃圾回收机制

Android

Java 虚拟机内存区域:深入解析

方法区

方法区是 Java 虚拟机 (JVM) 的一块内存区域,用于存储类型信息、常量、静态变量以及即时编译器编译后的代码缓存。它的本质是共享内存,所有线程都可以访问它。类型信息包括类的结构、方法签名和字段声明。常量包括字符串和数字。静态变量存储在类的静态成员中。代码缓存存储着即时编译器 (JIT) 编译的字节码,JIT 会将字节码转换为机器代码以提高性能。

堆是 JVM 中最大的内存区域,用于存储所有被实例化的对象。对象是程序执行过程中创建的实体,代表了程序中的数据。堆是一个动态内存区域,随着程序执行,对象会被创建和销毁。对象由引用指向,当对象不再被引用时,它就会被标记为可回收并最终被垃圾回收器回收。

虚拟机栈

每个线程都拥有自己的虚拟机栈。栈用于存储局部变量表、操作数栈、动态连接和方法出口。局部变量表存储着方法中的局部变量,操作数栈存储着操作数,动态连接存储着当前方法和调用它的方法之间的关系,方法出口存储着方法返回时的地址。栈是一种后进先出 (LIFO) 数据结构,这意味着最后压入栈中的元素将首先弹出。

本地方法栈

本地方法栈用于支持 Native 方法的执行。Native 方法是用 C 或 C++ 等非 Java 语言编写的,它们可以在 Java 程序中被调用。本地方法栈与虚拟机栈类似,但它存储的是 Native 方法的局部变量、操作数和方法出口。

程序计数器

程序计数器是一个与线程关联的小型内存区域,它记录了当前线程执行字节码的位置。如果线程正在执行 Java 方法,则程序计数器存储返回地址;如果线程正在执行 Native 方法,则程序计数器存储本地方法的起始地址。

垃圾回收机制

垃圾回收机制是 JVM 的一项重要功能,它负责回收不再被程序使用的内存空间,以避免内存泄漏和程序崩溃。

GC Roots

GC Roots 用于判定哪些对象是可达的,哪些对象是不可达的,从而确定哪些对象可以被回收。GC Roots 包括虚拟机栈中的局部变量、对象引用和本地方法栈中的引用。如果一个对象无法从 GC Roots 访问,则它被认为是不可达的,可以被回收。

safePoint

safePoint 是指在 JVM 执行过程中某些特定的点,在这个点上程序状态是确定的,并且不会出现引用关系的变更,可以安全地进行垃圾回收。在 safePoint,所有线程都会暂停,以便垃圾回收器可以标记和回收不可达的对象。

STW(Stop The World)

STW 是指在进行垃圾回收时,所有 Java 线程都必须暂停执行,直到垃圾回收完成。STW 暂停线程会降低应用程序的性能,因此 JVM 会尽力减少 STW 的持续时间。

CMS(Concurrent Mark Sweep)

CMS 是一种并发的垃圾回收算法,在进行垃圾回收时,Java 线程可以继续执行。CMS 算法首先标记不可达的对象,然后在单独的阶段中回收它们。CMS 算法可以减少 STW 的时间,但它也增加了垃圾回收的总开销。

分代回收算法

分代回收算法是一种优化算法,它将 Java 堆划分为不同的代,根据对象的生存周期,将对象分配到不同的代。

年轻代

年轻代用于存储新创建的对象。它分为 Eden 空间和 Survivor 空间。Eden 空间用于存储新创建的对象,Survivor 空间用于存储从 Eden 空间晋升上来的对象。随着时间的推移,对象从 Eden 空间晋升到 Survivor 空间,然后再晋升到老年代。

老年代

老年代用于存储从年轻代晋升上来的对象。它是一个比较稳定的区域,对象在老年代中存活的时间会比较长。

分代回收算法利用了对象的生存周期特点,将对象分配到不同的代,并对不同的代采用不同的垃圾回收算法,从而提高了垃圾回收的效率。

Davlik/ART

Davlik/ART 是 Android 平台上使用的虚拟机,它对 Java 虚拟机的内存区域和垃圾回收机制进行了优化。

Davlik 虚拟机

Davlik 虚拟机是 Android 2.2 到 Android 4.4 版本中使用的虚拟机,它采用解释执行的方式执行 Java 字节码。解释执行是一种将字节码逐条执行的解释过程。

ART 虚拟机

ART 虚拟机是 Android 5.0 版本中引入的虚拟机,它采用预先编译执行的方式执行 Java 字节码。预先编译执行是一种将字节码预先编译为机器代码的编译过程。

ART 虚拟机对 Java 虚拟机的内存区域和垃圾回收机制进行了优化,提高了虚拟机的性能和稳定性。

结论

Java 虚拟机内存区域和垃圾回收机制是 JVM 的重要组成部分。它们一起工作以确保 JVM 高效、可靠地运行。了解这些概念对于优化 Java 应用程序的性能和稳定性至关重要。

常见问题解答

  1. 什么是方法区?
    方法区是 JVM 中用于存储类型信息、常量、静态变量和即时编译器编译后的代码缓存的内存区域。
  2. 为什么堆是 JVM 中最大的内存区域?
    堆是最大的内存区域,因为它存储着所有被实例化的对象,即程序执行过程中创建的实体。
  3. 虚拟机栈在 JVM 中有什么作用?
    虚拟机栈用于存储局部变量表、操作数栈、动态连接和方法出口。
  4. 什么是 safePoint?
    safePoint 是 JVM 执行过程中某些特定的点,在这个点上程序状态是确定的,并且不会出现引用关系的变更,可以安全地进行垃圾回收。
  5. 分代回收算法如何提高垃圾回收的效率?
    分代回收算法根据对象的生存周期将对象分配到不同的代,并对不同的代采用不同的垃圾回收算法,从而提高了垃圾回收的效率。