专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 学习攻略 Java学习 告诉你什么是Java垃圾回收机制

告诉你什么是Java垃圾回收机制

更新时间:2022-06-02 10:13:48 来源:动力节点 浏览1056次

什么是Java垃圾回收机制?动力节点小编来为大家解答。

什么是垃圾回收?

垃圾收集是一种自动收集某个程序不再需要的内存区域并使该内存区域可供其他程序使用的技术。

程序的处理在垃圾回收执行过程中停止。因此,垃圾收集能否正常运行,极大地影响了系统性能。

程序中使用new创建的 Java 对象,占用 JavaVM 管理的内存空间。从创建 Java 对象到它变得多余的时间段称为Java对象的生命周期。

Java 对象有两种类型;寿命短的和寿命长的。对于在服务器上运行的 Java 应用程序,许多 Java 对象由请求和响应或事务管理创建。这些 Java 对象的生命周期很短,因为它们在处理结束时变得多余。另一方面,在应用程序运行时不断使用的 Java 对象具有较长的生命周期。

为了有效地执行垃圾回收,您需要通过对生命周期短的对象执行垃圾回收来使内存回收有效。避免对重复使用的长寿命对象进行不必要的垃圾回收,有助于防止系统性能下降。这是通过按代垃圾收集来实现的。

在按代垃圾回收中,Java 对象通过将它们分成两个区域进行管理;存储寿命短的对象的 New 区域和存储寿命长的对象的 Tenured 区域。New 区域进一步分为 Eden 区域和 Survivor 区域,Eden 区域保存最近使用new创建的对象,Survivor 区域保存即使多次运行垃圾收集后仍未收集的对象。执行垃圾收集超过固定次数的New区域的Java对象被认为是长期需要的Java对象,这些Java对象移动到Tenured区域。

下图显示了内存空间和按代垃圾回收管理的 Java 对象的概览:

分代垃圾回收执行的垃圾回收有以下两种类型:

复制垃圾收集

复制垃圾收集仅针对 Eden 区域和 Survivor 区域。当您使用 Eden 区域创建 Java 对象时,会发生复制垃圾收集。

您可以通过指定 Java HotSpot VM 选项来选择串行复制垃圾收集和并行复制垃圾收集。

因为串行复制垃圾回收的处理是并行执行的,所以可以高速执行并行复制垃圾回收。但是,如果您选择并行复制垃圾回收,则无法使用显式管理堆功能。

默认选择串行复制垃圾收集。请注意,本章介绍的内容适用于这两种类型的复制垃圾回收。

物体的寿命与年龄的关系

对一个对象执行复制垃圾回收的次数称为对象的年龄。

下图显示了一个对象的寿命和年龄之间的关系:

应用程序启动后,初始化过程完成,复制垃圾回收已经执行了多次,长期需要的长寿命对象移动到Tenured区。结果,在启动应用程序后不久,Java 堆就达到了稳定状态,并且大多数创建的 Java 对象都是生命周期较短的对象。特别是,如果新区域的调整已经适当执行,那么在 Java 堆稳定后,大部分生命周期较短的对象都会在第一次复制垃圾回收期间被回收。

复制垃圾回收机制

在JavaVM中,执行复制垃圾回收的New区的内存空间被划分为Eden区和Survivor区。Survivor 区域进一步分为 From 空间和 To 空间。From 空间和 To 空间具有相同的内存大小。

下图是New区域的配置:

Eden 区域是最初存储使用new创建的对象的区域。当在程序中执行new时,会分配来自 Eden 区域的内存。

当 Eden 区域变满时,将执行复制垃圾回收。复制垃圾回收中进行如下处理:

在 Eden 区域和 Survivor 区域的 From 空间中存在的 Java 对象中,正在使用的对象被复制到 Survivor 区域的 To 空间。未使用的 Java 对象将被销毁。

Survivor 区域的 To 空间和 From 空间被交换。

结果,Eden 区域和 To 空间变为空,而正在使用的对象保留在 From 空间中。

保存对象

将那些年龄未达到阈值的 Java 对象移动到 Tenured 区域的活动称为Saving。当 Eden 区域和 From 空间中正在使用的对象数量增加并且这些对象将被移动到的 To 空间的内存大小不足以在复制垃圾回收期间保存这些对象时,就会发生保存。在这种情况下,无法移动到 To 空间的对象将移动到 Tenured 区域。

当对象被保存时,原本不应该保存在Tenured区的寿命短的对象,被保存到Tenured区。如此反复,本应通过复制垃圾回收来回收的对象不断在内存空间中累积,从而增加 Java 堆的内存使用量,最终发生完整的垃圾回收。

不执行垃圾回收的区域(使用显式内存管理功能的显式堆区域)

在 JavaVM中,除了 Eden 区域、Survivor 区域和 Tenured 区域之外,您还可以使用称为Explicit heap的区域。垃圾回收不在显式堆区域中执行。

使用自动分配设置文件和显式内存管理功能 API 指定要保存在显式堆区域中的对象。在指定对象从 Survivor 区域移动到 Tenured 区域的时刻,指定对象被移动到 Explicit heap 区域。您可以指定没有被复制垃圾回收回收的长生命周期的对象,以减少Tenured区的内存使用,并防止完全垃圾回收的发生。您还可以使用显式内存管理功能或显式内存管理功能 API 的自动分配设置文件在显式堆区域中创建指定对象。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>