JVM 垃圾回收分配及算法

news2024/11/30 10:53:44

一、判断对象是否可以回收

垃圾收集器在做垃圾回收的时候,首先需要判定的就是哪些内存是需要被回收 的,哪些对象是「存活」的,是不可以被回收的;哪些对象已经「死掉」了,需 要被回收。 一般有两种方法来判断:

        引用计数器法:为每个对象创建一个引用计数,有对象引用时计数器 +1,引用被释放时计数 -1,当计数器为 0 时就可以被回收。它有一个缺点不能解决循环引用的问题

        可达性分析算法:从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。 当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是可以被回收的。

二、堆空间分配年轻代老年代及对应回收算法

堆主要用于存放各种类的实例对象和数组。在java中被分为两个区域:年轻代和老年代。 

年轻代和老年代的划分是为了更好的内存分派及回收。提高效率。堆是垃圾回收机制的重点区域。我们知道垃圾回收机制有三种,minor gc,major gc 和full gc。针对于堆的就是前两种。年轻代的叫 minor gc,老年代的叫major gc。 

1. 年轻代

年轻代中存在的对象是死亡非常快的,存在朝生夕死的情况。尺寸随堆大小的增加和减少而相应的变化,默认值是保持为堆的1/15。所以为了提高年轻代的垃圾回收效率,又将年轻代划分为三个区域: Eden区SurvivorFrom区SurvivorTo区

eden和survivor默认比例是8:1:1,进行垃圾回收采用的是分代复制算法(优点是避免内存碎片新创建的对象都会被分配到Eden区(如果该对象占用内存非常大,则直接分配到老年代区),当Eden区内存不够的时候就会触发MinorGC(Survivor满不会引发MinorGC,而是将对象移动到老年代中), 每次新生代的使用,会是eden区和一块survivor区。当我们进行垃圾回收的时候,清除正在使用的区域,将其中的存货对象,放入到另一个survivor区域并进行整理,保证空间的连续如果对象长时间存活,则将对象移动到老年区。“From”区和“To”区互换角色,原Survivor To成为下一次GC时的Survivor From区, 总之,GC后,都会保证Survivor To区是空的。存活下来的对象,他的年龄会增长1。当对象的年龄一次次存活,一次次增长,到达15的时候,这些对象就会移步到老年代。在年轻代执行gc的时候,如果老年代的连续空间小于新生代对象的总大小,就会触发一次full gc。是为了给新生代做担保,保证新生代的老年对象可以顺利的进入到老年代的内存区。

2. 老年代

随着Minor GC的持续进行,老年代中对象(年龄大于15的对象)也会持续增长,导致老年代的空间也会不够用,最终会执行Major GC(或full gc)(MajorGC 的速度比 Minor GC 慢很多很多,据说10倍左右),full gc会包含年轻代的gc。但老年代只要执行gc就一定是full gc。full gc使用的算法是:标记清除(回收)算法或标记压缩算法

标记无用对象,然后进行清除回收。 标记-清除算法(Mark-Sweep)是一种常见的基础垃圾收集算法,当进行标记清除时,会停止整个程序(stop the world),它将垃圾收集分为两个阶段:

        标记阶段:从根节点开始遍历,标记所有被引用的对象,一般在对象的header中标记为可达对象。

        清除阶段:collector对堆内存从头到尾进行线性遍历,如果发现某个对象的header没有标记为可达对象,则回收 。这里的回收是把对象的地址保存在空闲的地址列表中(内存分配),下次对象需要加载时,判断垃圾的位置空间是否够,如果够就存放覆盖原有的地址。

优点:实现简单,不需要对象进行移动。

缺点:标记、清除过程效率低,产生大量不连续的内存碎片,提高了垃圾回收的频率。 

3. 永久代(元空间)

在Java8中,永久代已经被移除,被一个称为“元数据区”(元空间,Metaspace)的区域所取代。
值得注意的是:元空间并不在虚拟机中,而是使用本地内存(之前,永久代是在jvm中)。这样,解决了以前永久代的OOM问题,元数据和class对象存在永久代中,容易出现性能问题和内存溢出,毕竟是和老年代共享堆空间。java8后,永久代升级为元空间独立后,也降低了老年代GC的复杂度。

元空间也是对java虚拟机的方法区的一种实现。元空间与永久代最大的区别在于,元空间不在虚拟机中,使用本地内存。通过配置如下参数可以更改元空间的大小。
        -XX:MetaspaceSize:初始空间的大小。达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
        -XX:MaxMetaspaceSize,最大空间,默认是没有限制的。
永久代的回收会随着full gc进行移动,消耗性能。每种类型的垃圾回收都需要特殊处理元数据。将元数据剥离出来,简化了垃圾收集,提高了效率。

三、其他垃圾回收算法

1. 复制算法(年轻代使用)

为了解决标记-清除算法的效率不高的问题,产生了复制算法。它把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾收集时,遍历当前使用的区域,把存活对象复制到另外一个区域中,最后将当前使用的区域的可回收的对象进行回收。

优点:按顺序分配内存即可,实现简单、运行高效,不用考虑内存碎片。

缺点:可用的内存大小缩小为原来的一半,对象存活率高时会频繁进行复制。

2. 标记-整理算法(标记压缩算法

在新生代中可以使用复制算法,但是在老年代就不能选择复制算法了,因为老年代的对象存活率会较高,这样会有较多的复制操作,导致效率变低。标记-清除算法可以应用在老年代中,但是它效率不高,在内存回收后容易产生大量内存碎 片。因此就出现了一种标记-整理算法(Mark-Compact)算法,与标记-清除算法不同的是,在标记可回收的对象后将所有存活的对象压缩到内存的一端,使他们紧凑的排列在一起,然后对端边界以外的内存进行回收。回收后,已用和未用的内存都各自一边。

优点:解决了标记-清理算法存在的内存碎片问题。

缺点:仍需要进行局部对象移动,一定程度上降低了效率。

参考:

JVM年轻代,老年代,永久代详解 - 经典鸡翅 - 博客园 (cnblogs.com)

jvm之年轻代(新生代)、老年代、永久代以及GC原理详解_老年代空间多大-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1824658.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习之---迁移学习

目录 一、什么是迁移学习 二、为什么需要迁移学习? 1. 大数据与少标注的矛盾: 2. 大数据与弱计算的矛盾: 3. 普适化模型与个性化需求的矛盾: 4. 特定应用(如冷启动)的需求。 三、迁移学习的基本问题有…

utm投影

一 概述 UTM (Universal Transverse Mercator)坐标系是由美国军方在1947提出的。虽然我们仍然将其看作与“高斯-克吕格”相似的坐标系统,但实际上UTM采用了网格的分带(或分块)。除在美国本土采用Clarke 1866椭球体以外&#xff0c…

聚观早报 | 深蓝G318价格发布;比亚迪方程豹豹3官图发布

聚观早报每日整理最值得关注的行业重点事件,帮助大家及时了解最新行业动态,每日读报,就读聚观365资讯简报。 整理丨Cutie 6月15日消息 深蓝G318价格发布 比亚迪方程豹豹3官图发布 夸克App升级高考AI搜索 iOS 18卫星通信实测 Redmi K70…

AI模型部署:Triton+Marker部署PDF转markdown服务

前言 在知识库场景下往往需要对PDF文档进行解析,从而能够通过RAG完成知识检索,本文介绍开源的PDF转Markdown工具marker,并借助Triton Inference Server将其服务化。 内容摘要 知识库场景下pdf解析简述Marker简介和安装Marker快速开始使用Tr…

Rust 实战丨绘制曼德博集

曼德博集 曼德博集其实是一个“没什么用”的发现。 曼德博集(Mandelbrot Set)是一种在复平面上形成独特且复杂图案的点的集合。这个集合是以数学家本华曼德博(Benoit Mandelbrot)的名字命名的,他在研究复杂结构和混沌…

LED显示屏色差处理方法

LED显示屏以其高亮度、低功耗和长寿命等优点,在广告、信息发布和舞台背景等领域得到广泛应用。然而,由于生产批次的不同,LED显示屏在亮度和色度上可能存在差异,影响显示效果。本文将探讨如何通过逐点校正技术来解决这一问题。 逐点…

【智源大会2024】(一)智源技术专题

智源的全家桶: 微调数据相关: 1.千万级数据集: BAAI创建了首个千万级别的高质量开源指令微调数据集。 2.模型性能与数据质量: 强调了模型性能与数据质量之间的高度相关性。 3.技术亮点: 使用了高质量的指令数据筛选与合成技术。这些技术显著提升了模型…

【ARM Cache 及 MMU 系列文章 6.5 -- 如何进行 Cache miss 统计?】

请阅读【ARM Cache 及 MMU/MPU 系列文章专栏导读】 及【嵌入式开发学习必备专栏】 文章目录 ARM Cache Miss 统计Cache 多层架构简介Cache 未命中的类型Cache 未命中统计Cache miss 统计代码实现Cache Miss 统计意义ARM Cache Miss 统计 在ARMv8/v9架构中,缓存未命中(Cache …

IIC通信总线

文章目录 1. IIC总线协议1. IIC简介2. IIC时序1. 数据有效性2. 起始信号和终止信号3. 数据格式4. 应答和非应答信号5. 时钟同步6. 写数据和读数据 2. AT24C023. AT24C02读写时序4. AT24C02配置步骤5. 代码部分1. IIC基本信号2. AT24C02驱动代码3. 实验结果分析 1. IIC总线协议 …

MAC系统下安装VUE

下载node.js 点击链接 选择图片中的稳定版本 安装node.js 打开终端,输入 node -v 和 npm -v 显示如上信息表示安装成功 安装vue脚手架🔧 sudo npm install -g vue/cli查看vue版本 vue -V6. 启动项目 1 采用 图形页面方式 控制台输入&#xff…

2024最新D卷 华为OD统一考试题库清单(按算法分类),如果你时间紧迫,就按这个刷

目录 专栏导读华为OD机试算法题太多了,知识点繁杂,如何刷题更有效率呢? 一、逻辑分析二、数据结构1、线性表① 数组② 双指针 2、map与list3、队列4、链表5、栈6、滑动窗口7、二叉树8、并查集9、矩阵 三、算法1、基础算法① 贪心思维② 二分查…

【c++进阶(三)】STL之vector的介绍和使用

💓博主CSDN主页::Am心若依旧💓 ⏩专栏分类c从入门到精通⏪ 🚚代码仓库:青酒余成🚚 🌹关注我🫵带你学习更多c   🔝🔝 vector的介绍 1.vector表示的是可变序列大小的容器 2、vector…

MySQL 日志(一)

本篇主要介绍MySQL日志的相关内容。 目录 一、日志简介 常用日志 一般查询日志和慢查询日志的输出形式 日志表 二、一般查询日志 三、慢查询日志 四、错误日志 一、日志简介 常用日志 在MySQL中常用的日志主要有如下几种: 这些日志通常情况下都是关闭的&a…

一文读懂Java线程池之线程复用原理

什么是线程复用 在Java中,我们正常创建线程执行任务,一般都是一条线程绑定一个Runnable执行任务。而Runnable实际只是一个普通接口,真正要执行,则还是利用了Thread类的run方法。这个rurn方法由native本地方法start0进行调用。我们看Thread类的run方法实现 /* What will be…

Mysql8.0.31开启mysqlbinlog

1、查看mysqlbinlog是否已经开启 show variables like %log_bin%; log_bin: ON是OFF否已经开启binlog log_bin_basename: binlog所在路径的文件开头前缀名 lob_bin_index: binlog文件的索引文件所在路径 2、若log_binOFF,则开启log_bin -- 退出mysql client ex…

open-amv开发环境搭建

open-amv是基于rv1103主控芯片的视觉开发板子 1.板子使用 板子使用type c作为调试口,同时供电,请在电脑上下载adb,当板子通过tpye c与电脑连接后,执行命令adb shell就会进入到板子的linux系统命令行。 2.编译环境 2.1 搭建doc…

【网络编程】优雅断开套接字连接

Linux的close函数和Windows的closesocket函数意味着完全断开连接。完全断开不仅指无法传输数据,而且也不能接收数据。 2台主机正在进行双向通信,主机A发送完最后的数据后,调用close函数断开了连接,之后主机A无法再接收主机B传输的…

超全Midjourney自学教程,怒码1万3千字!这是我见过最良心的教程啦!

前段时间,后台有网友私信我,说想跟我一起学AI~当时一边开心一边惶恐,满足于被人看到自己的努力、又担心自己是不是教不好别人,毕竟我自己也是业余时间边学边发的那种~ 不过,我还是会继续搬运或整理一些我认为值得记录…

C++100行超简单系统

非常好用&#xff0c;小白也可以自己修改 先来看图片&#xff1a; 用法附在代码里了&#xff01; #include <bits/stdc.h> #include <windows.h>using namespace std;struct users {string name;string num; bool f; } u[10000];int now_users 0; /*当前用户数*…

MyBatis使用 PageHelper 分页查询插件的详细配置

1. MyBatis使用 PageHelper 分页查询插件的详细配置 文章目录 1. MyBatis使用 PageHelper 分页查询插件的详细配置2. 准备工作3. 使用传统的 limit 关键字进行分页4. PageHelper 插件&#xff08;配置步骤&#xff09;4.1 第一步&#xff1a;引入依赖4.2 第二步&#xff1a;在m…