深入理解Java虚拟机:JVM高级特性与最佳实践-总结-3

news2024/11/25 11:27:31

深入理解Java虚拟机:JVM高级特性与最佳实践-总结-3

  • 垃圾收集器与内存分配策略
    • 垃圾收集算法
      • 标记-清除算法
      • 标记-复制算法
      • 标记-整理算法

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

垃圾收集算法

标记-清除算法

最基础的垃圾收集算法是“标记-清除”(Mark-Sweep)算法,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,也可以反过来,标记存活的对象,统一回收所有未被标记的对象。(标记过程使用可达性分析算法。)

后续的收集算法大多都是以标记-清除算法为基础,对其缺点进行改进而得到的。它的主要缺点有两个:

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

标记-清除算法的执行过程如下图所示。
在这里插入图片描述

标记-复制算法

标记-复制算法常被简称为复制算法。为了解决标记-清除算法面对大量可回收对象时执行效率低的问题,提出了一种称为“半区复制”(Semispace Copying)的垃圾收集算法,它将可用内存划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。 如果内存中多数对象都是存活的,这种算法将会产生大量的内存间复制的开销,但对于多数对象都是可回收的情况,算法需要复制的就是占少数的存活对象,而且每次都是针对整个半区进行内存回收,分配内存时也就不用考虑有空间碎片的复杂情况,只要移动堆顶指针,按顺序分配即可。这样实现简单,运行高效,不过其缺陷也显而易见,这种复制回收算法的代价是将可用内存缩小为了原来的一半。 标记-复制算法的执行过程如下图所示:
在这里插入图片描述

在1989年,Andrew Appel针对具备“朝生夕灭”特点的对象,提出了一种更优化的半区复制分代策略,
现在称为“Appel式回收”。HotSpot虚拟机的Serial、ParNew等新生代收集器均采用了这种策略来设计新生代的内存布局。Appel式回收的具体做法是把新生代分为一块较大的Eden空间和两块较小的Survivor空间,每次分配内存只使用Eden和其中一块Survivor。发生垃圾搜集时,将EdenSurvivor中仍然存活的对象一次性复制到另外一块Survivor空间上,然后直接清理掉Eden和已用过的那块Survivor空间。HotSpot虚拟机默认EdenSurvivor的大小比例是8∶1,也即每次新生代中可用内存空间为整个新生代容量的90%(Eden的80%加上一个Survivor的10%),只有一个Survivor空间,即10%的新生代是会被“浪费”的。当然,98%的对象可被回收仅仅是“普通场景”下测得的数据,任何人都没有办法百分百保证每次回收都只有不多于10%的对象存活,因此Appel式回收还有一个充当罕见情况的“逃生门”的安全设计,当Survivor空间不足以容纳一次Minor GC之后存活的对象时,就需要依赖其他内存区域(实际上大多就是老年代)进行分配担保(Handle Promotion)。

内存的分配担保好比我们去银行借款,如果我们信誉很好,在98%的情况下都能按时偿还,于是银行可能会默认我们下一次也能按时按量地偿还贷款,只需要有一个担保人能保证如果我不能还款时,可以从他的账户扣钱,那银行就认为没有什么风险了。内存的分配担保也一样,如果另外一块Survivor空间没有足够空间存放上一次新生代收集下来的存活对象,这些对象便将通过分配担保机制直接进入老年代,这对虚拟机来说就是安全的。

标记-整理算法

标记-复制算法在对象存活率较高时就要进行较多的复制操作,效率将会降低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选用这种算法。

针对老年代对象的存亡特征,提出了另外一种有针对性的“标记-整理”(Mark-Compact)算法,其中的标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存,“标记-整理”算法的示意图下图所示。标记-清除算法与标记-整理算法的本质差异在于前者是一种非移动式的回收算法,而后者是移动式的。是否移动回收后的存活对象是一项优缺点并存的风险决策
在这里插入图片描述
如果移动存活对象,尤其是在老年代这种每次回收都有大量对象存活区域,移动存活对象并更新所有引用这些对象的地方将会是一种极为负重的操作,而且这种对象移动操作必须全程暂停用户应用程序才能进行,像这样的停顿被最初的虚拟机设计者形象地描述为“Stop The World”

但如果跟标记-清除算法那样完全不考虑移动和整理存活对象的话,弥散于堆中的存活对象导致的空间碎片化问题就只能依赖更为复杂的内存分配器和内存访问器来解决。譬如通过“分区空闲分配链表”来解决内存分配问题(计算机硬盘存储大文件就不要求物理连续的磁盘空间,能够在碎片化的硬盘上存和访问就是通过硬盘分区表实现的)。内存的访问是用户程序最频繁的操作,甚至都没有之一,假如在这个环节上增加了额外的负担,势必会直接影响应用程序的吞吐量。基于以上两点,是否移动对象都存在弊端,移动则内存回收时会更复杂,不移动则内存分配时会更复杂。 从垃圾收集的停顿时间来看,不移动对象停顿时间会更短,甚至可以不需要停顿,但是从整个程序的吞吐量来看,移动对象会更划算。此语境中,吞吐量的实质是赋值器(Mutator,可以理解为使用垃圾收集的用户程序,为便于理解,多数地方用“用户程序”或“用户线程”代替)与收集器的效率总和。即使不移动对象会使得收集器的效率提升一些,但因内存分配和访问相比垃圾收集频率要高得多,这部分的耗时增加,总吞吐量仍然是下降的。HotSpot虚拟机里面关注吞吐量的Parallel Scavenge收集器是基于标记-整理算法的,而关注延迟的CMS收集器则是基于标记-清除算法的,这也从侧面印证这点。

另外,还有一种“和稀泥式”解决方案可以不在内存分配和访问上增加太大额外负担,做法是让虚拟机平时多数时间都采用标记-清除算法,暂时容忍内存碎片的存在,直到内存空间的碎片化程度已经大到影响对象分配时,再采用标记-整理算法收集一次,以获得规整的内存空间。前面提到的基于标记-清除算法的CMS收集器面临空间碎片过多时采用的就是这种处理办法。

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

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

相关文章

2023年推荐几款开源或免费的web应用防火墙

2023年推荐几款开源或免费的web应用防火墙 2023年,数字经济将强势崛起,并且成为新一轮经济发展的动力,传统的黑客破坏性攻击如CC,转为更隐蔽的如0day进行APT渗透。所以无论私有服务器还是云厂商如Cloudflare、阿里云、腾讯云等都…

无线安全操作(2)

目录 用户隔离 用户隔离介绍 1、集中式转发方式 2、分布式转发方式 用户隔离配置 用户隔离举例 用户静默排错帮助 ARP抑制 ARP抑制介绍 ARP抑制配置 ARP抑制举例 动态黑名单 动态黑名单概述 动态黑名单配置 动态黑名单举例 动态黑名单排错帮助 无线SAVI 无线…

正月初八,公司复工,我却失业了

昨天,一条吐槽刷屏。 方便大家阅读,原文先贴出来: 正月初八,公司复工,我却失业了。 一大早地铁转公交赶在九点前到达,老板在大门口迎接我们的到来,还发了一个红包,心里暖暖的。 到了…

以太坊EVM源码分析学习记录

EVM 待办清单结构与流程2020年版本的evm结构大致流程 opcodes.gocontract.goanalysis.gostack.gostack_table.goMemory.goMemory_table.goEVM.go区块上下文交易上下文EVM结构以太坊中的调用call、callcode和delegatecall创建合约 interpreter.gojump_table.goinstructions.goga…

极为罕见的大学生现象 凤毛麟角 是参加这种竞赛

大学里有哪些含金量较高,涉及到综合素质加分的竞赛呢? 一定要耐心耐心的看完 对你现在的境地会很有帮助!!! 大学生竞赛大致可以分为综合类和学科类两种。 综合类竞赛面向的范围更大,各个专业的学生均可参…

区块链论文一般发表在哪些地方?

区块链论文一般发表在哪些地方? 区块链论文发表区块链会议区块链会议论文阅读列表区块链相关论文查询论文检索网站 区块链论文发表 会议类: 安全、密码、分布式理论方面的会议:IEEE S&P (Oakland),、ACM CCS,、IACR Crypto、IACR Eurocr…

高通Camera IFE时钟配置

本文主要分享高通camera驱动中minHorizontalBlanking(最小水平消隐)和minVerticalBlanking(最小垂直消隐)配置项的计算方法; IFE时钟频率由以下sensor参数所决定: 对应sensor mode的输入IFE的帧尺寸(width…

微信小程序源码1000套

简介 不懂开发,但又想拥有自己的小程序怎么办?或者想要基于某个小程序框架做二次开发?如下截图,免费提供1000套微信小程序源码包合集(收集过程中发现网上资源大部分居然还要收费,真的很无语,人…

【TypeScript】TS条件类型(十)

🐱 个人主页:不叫猫先生 🙋‍♂️ 作者简介:2022年度博客之星前端领域TOP 2,前端领域优质作者、阿里云专家博主,专注于前端各领域技术,共同学习共同进步,一起加油呀! 💫优质专栏:vue3从入门到精通、TypeScript从入门到实践 📢 资料领取:前端进阶资料以及文中源…

【burpsuite安全练兵场-服务端9】服务端请求伪造SSRF漏洞-7个实验(全)

前言: 介绍: 博主:网络安全领域狂热爱好者(承诺在CSDN永久无偿分享文章)。 殊荣:CSDN网络安全领域优质创作者,2022年双十一业务安全保卫战-某厂第一名,某厂特邀数字业务安全研究员&…

UI自动化测试框架之cypress

​ 官网地址:JavaScript End to End Testing Framework | cypress.io testing tools cypress由一个免费的、开源的、本地安装的应用程序和一个用于记录您的测试的仪表服务组成。是前端测试的工具,解决开发人员和QA工程师在测试应用程序时面临的关键痛点…

跟光磊学Java-Windows版Java17开发环境搭建

如果想要开发Java程序/Java项目之前,必须要安装和配置JDK,这里的JDK表示Java17,不过下载软件的时候,强烈推荐大家一定要去软件的官网下载,因为官网提供的软件版本是最新的,会修复旧版本遗留的问题,这样我们…

教育edusrc证书站点漏洞挖掘

前言 以下涉及到的漏洞已提交至edusrc教育行业漏洞报告平台并已修复,该文章仅用于交流学习,切勿利用相关信息非法测试,如有不足之处,欢迎各位大佬指点。 正文 0x00 敏感信息泄漏 访问存在漏洞的站点首页,分析BurpS…

【数据科学赛】PromptCBLUE:首个中文医疗场景LLM评测基准 #¥16000

CompHub 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…)比赛。本账号会推送最新的比赛消息,欢迎关注! 更多比赛信息见 CompHub主页[1] 以下信息由AI辅助创作,仅供参考,请以官网为准(文末…

华为认证HCIA+HCIP题库(超500题含答案解析)

本套题库包含以下内容,覆盖数通Datacom方向HCIA和HCIP两科考题,考试代码为H12-811、H12-821、H12-831。有需要的可以直接拿。 首先来看看各科目的考试内容及分值占比。所有满分均为1000分,只需600分即可拿证,考试时间均为60分钟。…

CTF比赛必备常用工具

文中介绍的所有工具,均在压缩包中,结合本文更便于大家下载使用,快速上手。 CTF常用工具下载 CTF比赛必备常用工具 一、什么是CTF二、比赛中工具的重要性三、常用MISC(杂项)工具1. Audacity (提取莫斯密码辅…

C++【继承】

✨个人主页: 北 海 🎉所属专栏: C修行之路 🎃操作环境: Visual Studio 2019 版本 16.11.17 文章目录 🌇前言🏙️正文1、继承的概念1.1、本质1.2、作用1.3、实际例子 2、继承的定义2.1、格式2.2、…

linux创建新用户

只需要四步就能创建一个新的linux用户 1.打开终端 快捷键CtrlAltT 2.创建用户和密码 sudo useradd -m aaa 创建用户名为aaa的用户 -m:自动建立用户的登入目录 sudo是允许系统管理员让普通用户执行root命令的一个工具(获取权限) 这里会需要输…

Packet Tracer安装包及安装教程(8.0版本)

Packet Tracer安装包下载链接: 链接:https://pan.baidu.com/s/19BbCZzSxukKKdsdaqw7dHw 提取码:6666 (若果链接失效,可在评论区留言。) 安装步骤 1、解压缩文件,得到 cisco packet tr…

[架构之路-198] - 功能需求与分析:1张图、 4个阶段、16个步骤,系统分析问题与彻底解决问题的方法:问题界定、原因分析、方案确认、落实执行

目录 前言:一张图: 一、界定问题:找到真正的问题,问题就解决了一大半 1.发现异常: 2.优先顺序: 3.描述现状: 4.确定目标: 二、要因分析:透过表象,直达…