Java(JVM)中的垃圾收集


Java中的垃圾收集过程

Java中的垃圾回收会自动分配和释放内存,因此开发人员无需编写显式程序即可进行内存管理,这是Java编程的主要优势之一。

每当Java程序在JVM上运行时,对象都会在堆上创建,并且是专用于该程序的一部分内存。最终,将不再需要某些对象。该垃圾收集器发现这些未使用的对象,并删除以释放内存。

该 垃圾收集器将着眼于堆存储器,识别哪些对象是在使用中,哪些不是,并删除不再使用的对象。使用中的对象或引用的对象意味着程序的某些部分仍维护着指向该对象的指针。 程序的任何部分都不再引用未使用的对象或未引用的对象。因此,可以通过执行垃圾回收来回收未引用对象使用的内存。

1611232033179.png

内存的重新分配可以通过3个基本过程来描述:

  1. Marking
  2. Normal Deletion
  3. Deletion with Compacting

标记-识别正在使用但不是由垃圾收集器使用的内存块的过程,这是第一步

正常删除-删除未引用对象的过程,将引用对象和指针留给可用空间。

通过压缩 进行删除—除了删除未引用的对象之外,它还将通过将对象一起移动来压缩其余的引用对象,从而使 新的内存分配变得更加轻松和快捷。

JVM堆内存

1611150452770.png

Young Generation

新创建的对象始于年轻一代。年轻的一代也被称为托儿所,因为新的对象开始在这里居住。年轻一代又细分为一个Eden空间(其中所有新对象均在其中开始)和两个Survivor空间(其中一个对象在经历一个垃圾收集周期后从Eden中移出对象)。当对象是从Young Generation收集垃圾时,这些称为Minor垃圾收集事件,

  1. Eden Space 首先在伊甸园空间中创建所有新对象。当次要GC收集达到JVM决定的阈值时,它将启动。引用的对象从Eden空间移至第一个幸存者空间('Eden'和'from'->'to')。清除Eden空间后,未引用的对象将被删除。

  2. 幸存者0(S0)和幸存者1(S1) 两个幸存者空间(从和到)开始都是空的。 进行次要GC收集时,所有引用的对象都将移到幸存者空间。 GC结束后,将交换幸存者空间“从”和“到”角色(名称)。S1是先前垃圾回收(GC)期间的“收件人”角色。现在,S1已填充并充当“从”角色,而S0为空,将充当“到”角色。

Old Generation

较小的GC后,当老化的对象达到一定的年龄阈值时(默认情况下,现代JVM阈值设置为15个GC周期),它们将从年轻一代升级为老一代。寿命长的对象最终从年轻一代转移到了老一代。随着次要GC的继续发生,对象将继续提升到旧世代空间,并且将开始被填充并发生主要GC。当对象是从旧世代收集的垃圾时,将发生主要的垃圾收集。

Permanent Generation

类和方法之类的元数据存储在永久代中。不再使用的类可能是从永久代中收集的垃圾。在完全垃圾收集事件期间,所有代中未使用的对象将被垃圾收集。

1611232144136.png

垃圾收集类型(GC)

清除堆内存中不同部分的垃圾回收事件通常称为次要,主要和完全GC事件。但是,由于次要,专业和完全GC术语被广泛使用并且没有适当的定义,因此我们将介绍所有这些GC的解释。

Minor GC 从年轻一代空间收集垃圾称为次要GC。次要GC清洁年轻一代。当JVM无法为新对象分配空间时,即Eden空间变满时,总是触发次要GC。因此,分配率越高,次要GC发生的频率就越高。

Major GC

大型GC正在清理使用权(旧空间)。由于OLD Gen的大小较大,因此与年轻一代相比,GC发生的频率降低。当物体从上一代消失时,我们说发生了“大型GC”。老一辈的收藏家将尝试预测何时需要收集,以避免年轻一代的晋升失败。 收集器跟踪旧一代的填充阈值,并在超过该阈值时开始收集。如果此阈值不足以满足促销要求,那么将触发“ FullGC”。

Full GC

Full GC正在清理整个堆-无论是旧空间还是旧空间。许多人对Major(仅OLD代)和Full GC(Young + OLD(堆))感到困惑。FullGC涉及在收集和压缩旧一代后将所有活动对象从年轻一代升级到老一代。完整GC将是世界停止停顿。停止世界(Stop-the-World)确保收集器运行时未分配新对象,并且对象不会突然变得无法访问。


原文链接:http://codingdict.com