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/

相关推荐
兮动人12 分钟前
arthas之jvm相关命令
jvm·arthas·arthas之jvm相关命令·arthas基础命令
xcbeyond15 分钟前
Kubernetes 中 Java 应用性能调优指南:从容器化特性到 JVM 底层原理的系统化优化
java·jvm·云原生·kubernetes
钢铁男儿1 小时前
Python 序列构成的数组(对序列使用+和_)
服务器·windows·python
DogDaoDao1 小时前
从零开始:Windows 系统中 PowerShell 配置 FFmpeg 的详细步骤
windows·ffmpeg·音视频·ffplay·powershell·视频直播·ffprobe
sukalot2 小时前
Windows 图形显示驱动开发-WDDM 2.4功能-GPU 半虚拟化(十二)
windows·驱动开发
Thanwind4 小时前
关于JVM和OS中的栈帧的区别和内存浅析
java·jvm
快来卷java4 小时前
深入剖析 JVM:从组成原理到调优实践
java·jvm·spring boot·spring cloud·数据挖掘·maven
安 当 加 密5 小时前
如何在Windows服务器上搭建RADIUS认证服务器,有哪些开源方案和付费解决方案
服务器·windows·开源
三体世界8 小时前
C++ List的模拟实现
java·c语言·开发语言·数据结构·c++·windows·list
落淼喵_G14 小时前
【windows搭建lvgl模拟环境(一)之VSCode】
ide·windows·vscode