什么是自动垃圾收集?

自动垃圾收集是查看堆内存、确定哪些对象正在使用、哪些对象未使用并删除未使用对象的过程。正在使用的对象或引用的对象意味着程序的某些部分仍保留指向该对象的指针。未使用的对象或未引用的对象不再被程序的任何部分引用。因此,可以回收未引用对象使用的内存。

在 C 等编程语言中,分配和释放内存是一个手动过程。在 Java 中,释放内存的过程由垃圾收集器自动处理。基本过程可描述如下。

步骤 1:标记

该过程的第一步称为标记。垃圾收集器会在此步骤中识别哪些内存正在使用,哪些内存未使用。

引用的对象显示为蓝色。未引用的对象显示为金色。在标记阶段,将扫描所有对象以做出此决定。如果必须扫描系统中的所有对象,则这可能是一个非常耗时的过程。

第 2 步:正常删除

正常删除会移除未引用的对象,而留下引用的对象和指向可用空间的指针。

内存分配器保存对可以分配新对象的可用空间块的引用。

步骤 2a:压缩删除

为了进一步提高性能,除了删除未引用的对象外,您还可以压缩剩余的引用对象。通过将引用的对象一起移动,这使得新的内存分配变得更容易、更快捷。

为什么要进行分代垃圾收集?

如前所述,必须标记和压缩 JVM 中的所有对象,这是低效的。随着分配的对象越来越多,对象列表会越来越长,导致垃圾收集时间越来越长。然而,对应用程序的实证分析表明,大多数对象的寿命都很短。

以下是此类数据的一个示例。Y 轴显示已分配的字节数,X 轴显示随时间推移分配的字节数。

如您所见,随着时间的推移,分配的对象越来越少。事实上,大多数对象的寿命都很短,如图表左侧的较高值所示。

JVM 代数

从对象分配行为中学到的信息可用于增强 JVM 的性能。因此,堆被分解为更小的部分或代。堆部分包括:年轻代、老生代或终身代和永久代

年轻代是所有新对象分配和老化的地方。当年轻代填满时,将引发一次小型垃圾收集。小型收集可以在假设对象死亡率较高的情况下进行优化。充满死对象的年轻代会很快被收集。一些幸存的对象会老化,最终移至老一代。

Stop the World 事件- 所有次要垃圾收集都是"Stop the World"事件。这意味着所有应用程序线程都将停止,直到操作完成。次要垃圾收集始终是Stop the World 事件。

老生代用于存储长期存活的对象。通常,会为年轻代对象设置一个阈值,当达到该年龄时,对象就会移至老生代。最终需要收集老生代。此事件称为主要垃圾收集。

大型垃圾收集也是 Stop the World 事件。大型收集通常要慢得多,因为它涉及所有活动对象。因此,对于响应式应用程序,应尽量减少大型垃圾收集。另请注意,大型垃圾收集的 Stop the World 事件的长度受用于旧代空间的垃圾收集器类型的影响。

永久代包含JVM 所需的元数据,用于描述应用程序中使用的类和方法。JVM 在运行时根据应用程序正在使用的类填充永久代。此外,Java SE 库类和方法可能存储在此处。

如果 JVM 发现不再需要某个类,并且可能需要为其他类腾出空间,则可能会收集(卸载)该类。永久代包含在完整垃圾收集中。

相关推荐
xlsw_3 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹4 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭4 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫4 小时前
泛型(2)
java
超爱吃士力架4 小时前
邀请逻辑
java·linux·后端
南宫生4 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石4 小时前
12/21java基础
java
李小白665 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp5 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea
装不满的克莱因瓶5 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb