什么是自动垃圾收集?

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

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

相关推荐
IT毕设梦工厂3 分钟前
计算机毕业设计选题推荐-在线拍卖系统-Java/Python项目实战
java·spring boot·python·django·毕业设计·源码·课程设计
Ylucius37 分钟前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
七夜zippoe1 小时前
分布式系统实战经验
java·分布式
是梦终空1 小时前
JAVA毕业设计176—基于Java+Springboot+vue3的交通旅游订票管理系统(源代码+数据库)
java·spring boot·vue·毕业设计·课程设计·源代码·交通订票
落落落sss1 小时前
sharding-jdbc分库分表
android·java·开发语言·数据库·servlet·oracle
码爸1 小时前
flink doris批量sink
java·前端·flink
Monodye2 小时前
【Java】网络编程:TCP_IP协议详解(IP协议数据报文及如何解决IPv4不够的状况)
java·网络·数据结构·算法·系统架构
一丝晨光2 小时前
逻辑运算符
java·c++·python·kotlin·c#·c·逻辑运算符
无名指的等待7123 小时前
SpringBoot中使用ElasticSearch
java·spring boot·后端
Tatakai253 小时前
Mybatis Plus分页查询返回total为0问题
java·spring·bug·mybatis