JVM垃圾回收

JVM垃圾回收深度解析

我们的程序从主方法开始,所有申请的对象都是一层层的方法往下创建的。

如果一个方法中创建的内存对象,在方法执行完之后还需使用,程序必然需要在其上一层方法中,通过一个引用地址指向这个内存对象,这样一层层的引用就会形成一个引用链

对于那些在方法中创建,但在外部方法中,不需要使用的内存对象,我们也不会刻意在外层使用一个引用地址指向它,等方法执行完之后,这种对象就会变成游离状态

也就是我们可以回收的内存对象

这种通过判断一个对象是否可以基于引用链溯源到主方法中某个引用的算法 ,就是可达性分析算法

java虚拟机就是通过这种算法标记出所有不可回收的内存对象,然后就可以回收剩下没有别标记的垃圾内存。

一般有三种回收算法

1、标记清理法:就是清理那些可以回收的内存区域。

优缺点:标记清理算法虽然快,但是会产生碎片空间

2、复制法:把一整块内存分为两部分,每次只使用一半,垃圾回收时,把不需要回收的拷贝到另一半上,然后把当前一半全部清理掉。

优缺点:复制算法虽然没有碎片空间,但是只有一半内存可用。

3、标记整理法:就是把可回收的内存对象清理掉后,将剩余的对象整理到整块内存的头部。

优缺点:标记整理算法虽然既不浪费内存,也没有碎片空间但耗时长

在实际情况下,会将他们组合起来使用,一般情况下,Java虚拟机会把申请的内存区域划分为较小的新生代和较大的老年代两个区域

程序运行过程中,创建的对象会优先放置到新生代中,

对于那些经过多次垃圾回收,依然存活的对象则会迁移到老年代。

新生代 中使用的回收算法,就是复制法

因为大部分的内存对象,就是在那种子方法中创建,使用后就没有用了的对象,所以垃圾回收时,需要进行复制的对象很少,这样就能实现高效回收的同时,不产生碎片空间。

另外为了进一步提高内存的利用率,新生代又被分成了两个S区和一个E区一个S区仅占新生代总大小的1/10

每次使用时,都是使用一个S区和E区 ,当执行垃圾回收时,将S区和E区中不用回收的少量对象复制到另一个S区中,然后清空当前的S区和E区,如此一来便可以把内存的使用率从50%提高到90%

注:黄色为不可回收对象

问:如果复制的对象多S区放不下呢?

答:放不下的对象则会直接放到老年代,放心经过多年的实践证明,这种情况并不多。

老年代 则大部分使用标记整理算法

问:那标记整理算法不是很慢吗?并且在整理过程中为了防止程序随意操作内存,程序会被短暂的停顿。

答:早期的垃圾回收器基于单线程实现确实比较慢,一次垃圾回收可能让系统停顿数秒,但经过不断的发展,随着多线程增量回收,多区域划分等技术的引入如今的G1垃圾收集器已经可以将停顿时间稳定在100毫秒左右这在用户层面已经几乎没有感知了

学习笔记来源: https://v.douyin.com/i5T93R2M/

相关推荐
orient1 天前
JVM 调优实战:从监控告警到参数配置,一套完整方法论
jvm
orient1 天前
大白话 JVM:对象到底存在哪?GC 又是怎么运行的?
jvm
炸薯条!1 天前
从零开始学C++ (内存管理)
java·jvm·c++
yangshun_cug1 天前
Windows 11 的 WSL2 Ubuntu 22.04 安装 Seismic Unix 44R28 完整教程
windows·ubuntu·seismic unix
ManageEngine卓豪1 天前
Windows服务账户安全治理:特权访问自动化落地指南与工具选型
windows·pam·特权访问管理·特权账号
AxureMost1 天前
Xrecode 音频格式转换利器
windows·电脑
西西学代码1 天前
Flutter---StreamBuilder案例
javascript·windows·flutter
jiang_changsheng1 天前
Conda 的默认环境创建优先级。
linux·windows·python
黄一一9112431 天前
硬盘健康监测软件!绿色便携版!电脑硬盘还能用几年?CrystalDiskInfo工具帮你提前避开数据丢失
windows·电脑·硬件工程·开源软件
奇牙coding1 天前
gpt-5.6-luna 调用报 400 bad_request 怎么办?同样的 messages 在 gpt-5.5 没问题——两处校验差异和修复写法
java·windows·gpt·ai