📜  Java虚拟机-垃圾回收

📅  最后修改于: 2020-11-13 05:36:59             🧑  作者: Mango


Java对象的生命周期由JVM管理。一旦程序员创建了对象,我们就不必担心其剩余生命周期。 JVM将自动查找那些不再使用的对象,并从堆中回收它们的内存。

垃圾回收是JVM的一项主要操作,根据我们的需求对其进行调整可以使我们的应用程序获得巨大的性能提升。现代JVM提供了多种垃圾回收算法。我们需要了解应用程序的需求,以决定使用哪种算法。

您不能像使用非GC语言(如C和C++)那样,使用Java以编程方式取消分配对象。因此,您不能在Java中悬挂参考。但是,您可能具有空引用(引用是指JVM永远不会存储对象的内存区域)。每当使用null引用时,JVM都会引发NullPointerException。

请注意,尽管由于GC很少会在Java程序中发现内存泄漏,但确实会发生。我们将在本章结尾处创建内存泄漏。

以下GC用于现代JVM

  • 串行采集器
  • 吞吐量收集器
  • CMS收集器
  • G1收集器

上面的每种算法都执行相同的任务-查找不再使用的对象,并回收它们在堆中占用的内存。一种简单的方法是对每个对象具有的引用数进行计数,并在引用数变为0时将其释放(这也称为引用计数)。为什么这么天真?考虑一个循环链表。它的每个节点都将对其进行引用,但是整个对象不会在任何地方被引用,因此理想情况下应将其释放。

JVM不仅释放内存,还将小内存卡盘合并成更大的内存。这样做是为了防止内存碎片。

简单地说,典型的GC算法执行以下活动-

  • 查找未使用的对象
  • 释放它们在堆中占用的内存
  • 合并片段

GC必须在运行时停止应用程序线程。这是因为它在运行时会四处移动对象,因此无法使用这些对象。这种停止称为“世界停止”,我们在调整GC时要达到使这些停止的频率和持续时间最小化的目的。

记忆合并

下面显示了内存合并的简单演示

记忆合并

阴影部分是需要释放的对象。即使在收回所有空间之后,我们也只能分配最大大小为75Kb的对象。甚至在我们有200Kb的可用空间后,如下所示

阴影部分