什么是自动垃圾收集?

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

在 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 发现不再需要某个类,并且可能需要为其他类腾出空间,则可能会收集(卸载)该类。永久代包含在完整垃圾收集中。

相关推荐
小二·6 分钟前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic29 分钟前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
懒洋洋大魔王31 分钟前
RocketMQ的使⽤
java·rocketmq·java-rocketmq
武子康36 分钟前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
转世成为计算机大神1 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
qq_327342731 小时前
Java实现离线身份证号码OCR识别
java·开发语言
阿龟在奔跑3 小时前
引用类型的局部变量线程安全问题分析——以多线程对方法局部变量List类型对象实例的add、remove操作为例
java·jvm·安全·list
飞滕人生TYF3 小时前
m个数 生成n个数的所有组合 详解
java·递归
代码小鑫3 小时前
A043-基于Spring Boot的秒杀系统设计与实现
java·开发语言·数据库·spring boot·后端·spring·毕业设计
真心喜欢你吖3 小时前
SpringBoot与MongoDB深度整合及应用案例
java·spring boot·后端·mongodb·spring