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/

相关推荐
小王努力学编程38 分钟前
高并发内存池(三):TLS无锁访问以及Central Cache结构设计
jvm·数据结构·c++·学习
星星点点洲1 小时前
JVM对象分配与程序崩溃排查
jvm
辛普森Mmmm1 小时前
JVM详解
jvm
simple_whu2 小时前
开启WSL的镜像网络模式
windows·wsl
huangyuchi.5 小时前
【C++】智能指针
开发语言·jvm·c++·笔记·c++11·智能指针·shared_ptr
modest —YBW5 小时前
Ollama+OpenWebUI+docker完整版部署,附带软件下载链接,配置+中文汉化+docker源,适合内网部署,可以局域网使用
人工智能·windows·docker·语言模型·llama
code在飞6 小时前
windows 部署 Kafka3.x KRaft 模式 不依赖 ZooKeeper
windows·分布式·zookeeper·kafka
不会飞的鲨鱼7 小时前
Windows系统下使用Kafka和Zookeeper,Python运行kafka(二)
windows·zookeeper·kafka
2501_9153738817 小时前
Electron 打包与发布指南:让你的应用运行在 Windows、macOS、Linux
windows·macos·electron
小羊学伽瓦18 小时前
【Java基础】——JVM
java·jvm