当前位置: 首页 > news >正文

垃圾收集器与内存分配策略

Java的垃圾收集器(Garbage Collection,简称GC)

垃圾收集器需要完成三件事:

  1. 哪些内存需要回收
  2. 什么时间回收
  3. 如何回收

第一步垃圾收集器需要找出哪些内存需要回收,这就需要垃圾回收算法找出哪些对象可以回收

找出哪些对象需要回收(标记算法)

引用计数算法

在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一,当引用失效时,计数器值就减一;任何时刻计数器为零的对象就不可能再被使用。

客观来说,虽然引用计数算法(Reference Counting)占用了一些额外的内存空间来计数,但是原理简单,判定效率很高,缺点是存在相互循环引用的问题。

即两个对象相互引用,但是并没有其他任何其他对象引用这两个对象,导致这两个对象的引用计数器值为1,但是这两个对象已经没办法被使用,并且引用计数算法也无法回收它们。

可达性分析算法

当前主流商用程序语言的内存管理子系统均是采用可达性分析(Reachability Ayalysis)算法判定对象是否存活,该算法的基本思路是通过一系列成为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”(Reference Chain),如果某个对象到GC Roots间没有任何引用链相连,则证明该对象是不可能再被使用的。

在Java体系中,固定可作为GC Roots的对象有以下几种:

  1. 在虚拟机栈(栈帧中的本地变量表)中引用的对象,如正在运行的方法中用到的参数,局部变量,临时变量等
  2. 在方法区中类静态属性引用的对象
  3. 在方法区中常量引用的对象
  4. 在本地方法栈中JNI(即Native方法)引用的对象
  5. JVM内部的引用,如基本数据类型对应的Class对象等,还有系统类加载器
  6. 所有被同步锁(synchronized关键字)持有的对象
  7. 反映JVM内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等

除了这些固定的GC Roots集合外,根据用户所选用的垃圾收集器以及当前回收的内存区域不同,还有其他对象“临时性”加入,共同构成完成的GC Roots集合。

垃圾收集算法

标记-清除算法

算法分为标记和清除两个阶段,首先标记出所有需要回收的对象,在标记完成之后,统一回收所有被标记的对象,也可反过来,标记存活对象,统一回收所有未被标记的对象。标记过程就是上面的标记算法。

缺点:第一,执行效率不稳定,若Java堆中包含大量对象且大部分需要回收,这时必须进行大量标记和清除的动作,导致标记和清除两个过程的执行效率都随着对象数量增长而降低。第二,内存空间碎片化问题,标记和清除之后会产生大量不连续的内存碎片,碎片太多导致后续如需分配大对象时无法找到足够的连续内存空间,而不得不提前触发另一次垃圾收集动作。

标记-复制算法

标记-复制算法简称复制算法,为了解决标记-清除算法执行效率低的问题,提出标记-复制算法。即它将可用内存按照容量均分为两部分,每次只使用其中额一块。当另一块用完了,就将还存活的对象复制到另一块上面,然后再将已经使用过的内存全部清理掉。

优点:不会产生内存碎片,存活对象较少时,实现简单执行效率高

缺点:浪费空间;当存活对象较多时,会产生大量内存间复制的开销

新生代“朝生夕灭”的特点,即新生代的对象有98%熬不过第一轮收集,因为不需要1:1的比例划分新生代的内存空间。

提出了一种更优化的半区复制分代策略,称为“Appel式回收”,HotSpot虚拟机Serial、ParNew等新生代收集器均采用了这种策略来设计新生代的布局。

即把新生代分为一块较大的Eden空间和两块较小的Survivor空间,每次分配内存只使用Eden和其中一块Survivor空间。发生垃圾收集时,将Eden和Survivor中仍然存活的对象一次性复制到另外一块Survivor空间,然后直接清理掉Eden和已用过Survivor空间。

HotSpot虚拟机默认Eden和Survivor的大小比例是8:1,即每次新生代中可用内存空间为整个新生代容量的90%(Eden 80% + 一块Survivor 10%),提高空间利用率。

标记-整理算法

标记-复制算法在对象存活较高时就要进行较多复制操作,效率会降低,标记-复制算法仅适合新生代区域的回收。当遇到老年代区域中时不适合。

针对老年代对象的存亡特征,提出标记-整理(Mark-Compact)算法,标记过程仍然与“标记-清除”算法相同,然后将所有存活的对象都向空间一端移动,然后直接清除掉边界以外的内存。

 

http://www.gsyq.cn/news/114955.html

相关文章:

  • GUI Agent vs 传统UI开发:效率提升300%的秘密
  • 电脑新手必看:Windows安装失败怎么办?
  • 1小时搭建:基于Windows Server 2016的测试环境原型
  • 零基础教程:图解Linux安装Python全流程
  • UG\NX二次开发,根据对称面计算对称向量对称点的方法
  • Dockerfile 随记
  • 用ToDesk+Ubuntu构建远程实验室原型
  • AI Agent在金融风险分析中的应用
  • 《60天AI学习计划启动 | Day 35: 前端 AI 调试面板(日志 / 请求回放》
  • 低成本实现专业级语音合成:EmotiVoice是你的首选
  • Odoo 中的不同用户类型详解
  • Windows11 26H1 游戏版!电脑系统安装使用教程! Windows11 26H1
  • 伏昔尼布VORANIGO显著延长低级别胶质瘤无进展生存期【海得康】
  • vue基于springboot的高校教师科研项目管理系统的设计与实现
  • Python 学习技术文章大纲基础语法与核心概念
  • 自动化测试框架搭建:持续验证EmotiVoice输出质量
  • EmotiVoice语音合成与音乐背景融合技巧:制作电台节目
  • 2025年全日制托管学校权威指南:破解成长困境,择校更需专业 - 深度智识库
  • 情感语音数据库建设:助力EmotiVoice持续迭代
  • 基于SpringBoot+Vue的大学生一体化服务系统源码文档部署文档代码讲解等
  • 每天一个网络知识:什么是 VXLAN?
  • EmotiVoice语音合成系统自动化测试框架搭建经验
  • 结合ASR构建完整对话系统:EmotiVoice的角色定位
  • 实用指南:智能化制造与工业互联网的未来:企业数字化转型的关键力量
  • DevExtreme JS ASP.NET Core v25.2预览 - DataGrid/TreeList全新升级
  • 四川省自建房设计公司/机构权威测评推荐排行榜 - 苏木2025
  • 烟草复烤 “洞道干燥 AI 风门”:把出料水分标准差压到 0.11%,复烤损耗再降 0.8‰​
  • 数据安全人才缺口扩大 2025年需求达150万人 - 金海境科技
  • 城市污水厂 “AAO 工艺 AI 鼓风量” 模型:把吨水电耗降到 0.21 kWh,一年跑出 600 万度电
  • STM32通过PWM实现呼吸灯效果:代码详解与硬件连接