天天快资讯:从原理聊JVM(一):染色标记和垃圾回收算法
作者:京东科技康志兴
1 JVM运行时内存划分1.1 运行时数据区域• 方法区
属于共享内存区域,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。运行时常量池,属于方法区的一部分,用于存放编译期生成的各种字面量和符号引用。
(相关资料图)
JDK1.8之前,Hotspot虚拟机对方法区的实现叫做永久代,1.8之后改为元空间。二者区别主要在于永久代是在JVM虚拟机中分配内存,而元空间则是在本地内存中分配的。很多类是在运行期间加载的,它们所占用的空间完全不可控,所以改为使用本地内存,避免对JVM内存的影响。根据《Java虚拟机规范》的规定,如果方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。
• 堆
线程共享,主要是存放对象实例和数组。如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OutOfMemoryError异常。PS:实际上写入时并不完全共享,JVM会为线程在堆上划分一块专属的分配缓冲区来提高对象分配效率。详见:TLAB
• 虚拟机栈
线程私有,方法执行的过程就是一个个栈帧从入栈到出栈的过程。每个方法在执行时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。如果线程入栈的栈帧超过限制就会抛出StackOverFlowError,如果支持动态扩展,那么扩展时申请内存失败则抛出OutOfMemoryError。
• 本地方法栈
和虚拟机栈的功能类似,区别是作用于Native方法。
• 程序计数器
线程私有,记录着当前线程所执行的字节码的行号。其作用主要是多线程场景下,记录线程中指令的执行位置。以便被挂起的线程再次被激活时,CPU能从其挂起前执行的位置继续执行。唯一一个在 Java 虚拟机规范中没有规定任何 OutOfMemoryError 情况的区域。注意:如果线程执行的是个java方法,那么计数器记录虚拟机字节码指令的地址。如果为native(底层方法),那么计数器为空。
1.2 对象的内存布局在 HotSpot 虚拟机中,对象分为如下3块区域:
• 对象头(Header)运行时数据:哈希码、GC分代年龄、锁状态标志、偏向线程ID、偏向时间戳等。类型指针:对象的类型元数据的指针,如果对象是数据,还会记录数组长度。
• 对象实例数据(Instance Data)包含对象真正的内容,即其包括父类所有字段的值。
• 对齐填充(Padding)对象大小必须是是8字节的整数倍,所以对象大小不满足这个条件时,需要用对齐填充来补齐。
2 标记的方法和流程2.1 判断对象是否需要被回收要分辨一个对象是否可以被回收,有两种方式:引用计数法和可达性算法。
• 引用计数法就是在对象被引用时,计数加1,引用断开时,计数减1。那么一个对象的引用计数为0时,说明这个对象可以被清除。这个算法的问题在于,如果A对象引用B的同时,B对象也引用A,即循环引用,那么虽然双方的引用计数都不为0,但如果仅仅被对方引用实际上没有存在的价值,应该被GC掉。
• 可达性算法通过引用计数法的缺陷可以看出,从被引用一方去判定其是否应该被清理过于片面,所以我们可以通过相反的方向去定位对象的存活价值:一个存活对象引用的所有对象都是不应该被清除的(Java中软引用或弱引用在GC时有不同判定表现,不在此深究)。这些查找起点被称为GC Root。
2.2 哪些对象可以作为GC Root呢?JAVA虚拟机栈中的本地变量引用对象
方法区中静态变量引用的对象
方法区中常量引用的对象
本地方法栈中JNI引用的对象
2.3 快速找到GC Root - OopMap栈与寄存器都是无状态的,保守式垃圾收集
会直接线性扫描栈,再判断每一串数字是不是引用,而HotSpot采用准确式垃圾收集
方式,所有对象都存放在OopMap(Ordinary Object Pointer)中,当GC发生时,直接从这个map中寻找GC Root。
将GC Root存放到OopMap有两个触发时间点:
类加载完成后,HotSpot就会把对象内什么偏移量上是什么类型的数据计算出来。
即时编译过程中,也会在特定的位置记录下栈里和寄存器里哪些位置是引用。
2.4 更新OopMap的时机 - 安全点导致OopMap更新的指令非常多,所以HotSpot只在特定位置进行记录更新,这些位置叫做安全点
。安全点位置的选取的标准是:“是否具有让程序长时间执行”。比如方法调用、循环跳转、异常跳出等等。
• 白色:表示垃圾回收过程中,尚未被垃圾收集器访问过的对象,在可达性分析开始阶段,所有对象都是白色的,即不可达。
• 黑色:被垃圾收集器访问过的对象,且这个对象所有的引用均扫描过。黑色的对象是安全存活的,如果其他对象被访问时发现其引用了黑色对象,该黑色对象也不会再被扫描。
• 灰色:被垃圾收集器访问过的对象,但这个对象至少有一个引用的对象没有被扫描过。那么标记阶段就是从GC Root的开始,沿着其引用链将每一个对象从白色标记为灰色最后标记为黑色的过程。
标记过程中不一致问题由于这个阶段是层层递进的标记,所以过程中难免出现不一致的情况导致原本是黑色的对象被标记为白色,比如,当前扫描到B对象了,C对象尚未被访问时,标记情况如下:
那么如果这时A对象取消了对B对象的引用,而GC Root增加了对C对象的引用,GC Root作为黑色标记不会再次被扫描,那么C对象在标记阶段结束后仍然会保持白色,就会被清除掉。
解决方式• 增量更新
当黑色对象增加了对白色对象的引用时,将其从黑色改为灰色,等并发标记阶段结束后,从GC Root开始顺着对象图再将灰色对象重新扫描一次,这个扫描过程会STW,不会再次产生不一致问题。CMS就采用了这种方式。
• 原始快照(SATB)
当灰色对象删除了白色对象的引用时,将其记录在线程独占的SATB Queue中,让其在标记阶段结束后被再次扫描。 G1、Shenandoah采用了这种方式。
示例我们通过一个例子来展示两种处理方式的不同,比如正常标记到对象A时,将其标记为灰色:
此时,用户线程发生如下行为:
GC Root直接引用了C
A取消了引用B
理论上,C仍然是可达对象,不应被清除,而B不可达,应当被清除。
增量更新会记录行为1,将GC Root标记为灰色,B不能访问到被标记为可以回收:
等到重新标记阶段再次访问灰色的GC Root,顺序将GC Root和C标记为黑色:
而原始快照会记录行为2,将发生引用变化的对象全部记录下来,等到重新标记阶段再次访问这些灰色,将其标记为黑色并顺着对象图扫描。
那么最终B作为浮动垃圾就被保存下来了,只能等到下一次GC时才能被回收。
3 分代模型3.1 分代假说弱分代假说(WeakGenerationalHypothesis):绝大多数对象都是朝生夕灭的。 强分代假说(StrongGenerationalHypothesis):熬过越多次垃圾收集过程的对象就越难以消亡。 跨代引用假说(IntergenerationalReferenceHypothesis):跨代引用相对于同代引用来说仅占极少数。
上述假说是根据实际经验得来的,由此垃圾收集器通常分为“年轻代”和“年老代”:
• 年轻代用来存放不断生成且生命周期短暂的对象,收集动作相对高频
• 年老代用来存放经历多次GC仍然存活的对象,收集动作相对低频
3.2 空间分配担保如果在GC后新生代存货对象过多,Survivor无法容纳,那么将会把这些对象直接送入年老代,这就叫年老代进行了“分配担保”。 为了保证年老代能够足够空间容纳这些直接晋升的对象,在发生Minor GC之前,虚拟机必须先检查年老代最大可用的连续空间,如果大于新生代所有对象总空间或者历次晋升的平均大小,就会进行MinorGC,否则将进行FullGC以同时清理年老代。
3.3 记忆集和卡表记忆集是一种用于记录从非收集区域指向收集区域的指针集合的抽象数据结构。记忆集的作用新生代发生垃圾收集时(Minor GC),如果想确定这个新生代对象是否被年老代的对象引用,则需要扫描整个年老代,成本非常高。
如果我们能知道哪一部分年老代可能存在对新生代的引用,就可以降低扫描范围。
所以我们可以在新生代建立一个全局数据结构叫“记忆集(Remembered Set)”,这个结构把年老代分为若干个小块,标记了哪些小块内存中存在引用了新生代对象的情况,等到Minor GC时,只扫描这部分存在跨代引用的内存块即可。虽然在对象变化时增加了维护记忆集的成本,但相比垃圾收集时扫描整个年老代来说是值得的。
JVM通常在对象增加引用前设置写屏障判断是否发生跨代引用,如果有跨代情况,则更新记忆集。
卡表实现记忆集时,可以有不同精度的粒度:可以指向内存地址,也可以指向某个对象,或者指向某一块内存区域。精度越低,维护成本越低。指向某一块内存区域的实现方式就是“卡表”。卡表通常就是一个byte数组,数组中每一个元素代表某一块内存,其值是1或者0:当发生跨代引用时,就表示该元素“dirty”了,那么将将其设置为1,否则就是0。
4 垃圾回收算法4.1 标记-清除(Mark-Sweep)GC分为两个阶段,标记和清除。首先标记所有可回收的对象,在标记完成后统一回收所有被标记的对象。
缺点是清除后会产生不连续的内存碎片。碎片过多会导致以后程序运行时需要分配较大对象时,无法找到足够的连续内存,而不得已再次触发GC。
4.2 标记-复制(Mark-Copy)将内存按容量划分为两块,每次只使用其中一块。当这一块内存用完了,就将存活的对象复制到另一块上,然后再把已使用的内存空间一次清理掉。
这样使得每次都是对半个内存区回收,也不用考虑内存碎片问题,简单高效。
缺点需要两倍的内存空间。
一种优化方式是使用eden和survivior区,具体步骤如下:
eden和survivior区默认内存空间占比为8:1:1,同一时间只使用eden区和其中一个survivior区。标记完成后,将存活对象复制到另一个未使用的survivior区(部分年龄过大的对象将升级到年老代)。
这种做法,相比普通的两块空间的标记复制算法来说,只有10%的内存空间浪费,而这样做的原因是:大部分情况下,一次young gc后剩余的存活对象非常少。
4.3 标记-整理(Mark-Compact)标记-整理也分为两个阶段,首先标记可回收的对象,再将存活的对象都向一端移动,然后清理掉边界以外的内存。
此方法避免标记-清除算法的碎片问题,同时也避免了复制算法的空间问题。 一般年轻代中执行GC后,会有少量的对象存活,就会选用复制算法,只要付出少量的存活对象复制成本就可以完成收集。
而年老代中因为对象存活率高,用标记复制算法时数据复制效率较低,且空间浪费较大。所以需要使用标记-清除或者标记-整理算法来进行回收。
所以通常可以先使用标记清除算法,当碎片率高时,再使用标记整理算法。
5 最后本篇介绍了JVM中垃圾回收器相关的基础知识,后续会深入介绍CMS、G1、ZGC等不同垃圾收集器的运作流程和原理,欢迎关注。
标签:
推荐文章
- 天天快资讯:从原理聊JVM(一):染色标记和垃圾回收算法
- 对师德违规零容忍!教育部发布《关于推开教职员工准入查询工作的通知》
- 京东科技高管再调整,徐丰升任京东科技总裁 当前快报-每日时讯
- 矫情
- 世界焦点!莙达菜_莙达菜
- 清扬洗发水广告代言人(清扬洗发水广告)
- 【当前热闻】股票行情快报:合力科技(603917)4月21日主力资金净卖出485.07万元
- 福建发布科技攻关榜单 广邀英雄“揭榜挂帅”
- 两岁男童头卡防盗窗 小伙爬楼托举五十分钟救援 今日最新
- 牺牲生活质量的攒钱方式,没有参考意义 环球信息
- 海兴电力(603556.SH)发布2022年度业绩,净利润6.64亿元,增长111.71%,拟10派7元
- 湖人消息:老詹展现排面,水拉创尴尬纪录,浓眉自信反弹_全球快看点
- 每日快看:国土规建环保安监所是什么意思呀_国土规建环保安监所是什么意思
- incipio在中国有办公室吗_incipio 环球观点
- 如何烤橡子南瓜
- 天天微头条丨0420早盘策略:沪指剑指3400,6G有望二度开花
- 湘西州水利局组织观看电影党课影片《何叔衡》
- 观焦点:投诉劳动纠纷有用吗
- 方盛制药股东户数下降5.44%,户均持股19.38万元
- “热爱乐山好市民”经典案例(十)
- 汇丰 HSBC宣布推出基于AI的股票指数——AI全球战术指数 HSBC AI Global Tactical Index-环球滚动
- 23金街01票面利率为3.2900%
- 天天新动态:新出游戏_新出医生
- 美银:美股夏季反弹仍可期,投资者不要在5月“离场”
- 售楼保洁工作总结(必备7篇)
- 金山股份股票简称将变更为“*ST金山” 4月21日停牌1天
- 白酒存量时代的危与机|全球快播报
- 圆周率的近似计算公式 圆周率得来的计算公式
- 北京西城:结对共建 筑牢金融风险“防火墙”_环球微动态
- 使用 Spring Cloud Bus 向指定的微服务发送消息
- 热头条丨生车前草危险吗?
- 世界速读:Cortica care获得7500万美元D轮融资
- 大摩:维持中国电信(00728)“增持”评级 目标价5港元
-
环球今亮点!蘸谷雨之墨
和人才之曲 - 五华区气象局解除大风蓝色预警【Ⅳ级/一般】-世界消息
- 三位董事齐聚上海,宝马升级在华布局|聚焦2023上海车展-环球微速讯
- 上海今年首轮“抢地大战”打响 多家头部房企回归
- 北京丰台:长峰医院过火的东楼已按要求封闭 院内环境已完成清理
- 世界消息!28人惨遭淘汰!樊振东 孙颖莎今首秀,伊藤美诚今晚或出局~陈梦再战日本一姐!附4.19日赛程
- 慰问演出 关爱老人
- 秋葵做法大全家常菜视频_秋葵做法大全家常_世界播报
- 单身青年职工共赴春光游“缘”会 全球速讯
- 当前资讯!元旦联欢会节目单模板_元旦联欢会节目
- 农业农村部答21记者: 今年以来我国农产品市场供应充足 价格总体平稳|今日观点
- 六台:阿拉巴将伤缺2周,目标国王杯决赛复出&能出战与曼城首回合_观热点
- 今亮点!财报里的真相|均瑶健康2022年增收不增利 “乳酸菌第一股”的乳酸菌饮品收入下滑
- 内蒙古鄂尔多斯:夫妻双方住房公积金贷款额度提至80万元|今日热门
- 辽宁省13个部门联合印发《实施意见》加强新就业形态劳动者权益保障|世界观察
- 巴伐利亚州长:多特蠢得没法赢德甲 拜仁球员要少搞时尚好好踢球 环球快讯
- “宁王”一线工人:做四休三想加班,没活干盼着忙起来-全球简讯
- 法治赋能助力青少年法治教育工作提质增效 ——天水市印发加强青少年法治宣传教育工作实施方案
- 瓦格纳曝配备T-90M重型坦克,现在连天气也对俄罗斯有利
- 硬盘重映射扇区计数怎么修复_重新映射的扇区事件计数c4-世界微动态
- 赶超偏股混合、接近权益产品!成立近半年这类新产品99%实现盈利|天天热闻
X 关闭
最新资讯
- 安全为首 枣庄市中光明路街道筑牢教育安全屏障
- 龙虎榜|杭叉集团今日涨停,机构合计净买入3549.76万元
- “中国全功能接入互联网30周年系列活动”启动-头条焦点
- 最新快讯!作文素材大全100字初中_作文素材大全100字
- 汇成股份(688403.SH)发布2022年度业绩,净利润1.77亿元,同比增长26.3%|天天短讯
- 中国足彩网北单20日推荐:埃梅莱克阵容厚度有限_速看料
- 焦点资讯:马斯克谈特斯拉利润率:仍领跑行业 降价促销后未来用软件回补利润
- 和邦生物(603077):4月20日北向资金增持59.29万股 天天快资讯
- 越来越多村干部主动离职,他们为什么不愿意干了?4个原因很现实
- cf修改游戏客户端封号 cf修改游戏客户端是什么意思
- 爷青回!零点电影院爆满 《灌篮高手》打破纪录!-每日关注
- 全球热头条丨东西协作 鲁渝有约|万重山,千里情,淄博石柱一家亲!
- 前沿热点:[游戏] EasyGame C++
- 铜川市气象台发布大风蓝色预警【Ⅳ级/一般】 焦点热闻
- 2023年宁波市新一期消费券领券指南_世界微头条
- 炒菜锅上的铁锈吃多了会怎样(铁上有锈怎么快速去掉) 当前速递
- 郑建华受审,涉案1.56亿|全球聚焦
- 世界速讯:苏州古运河游船码头时间表
- 珀莱雅:2022年净利润同比增长41.88% 拟10转4派8.7元
- 东方嘉盛:公司目前经营活动正常
- 楼继伟:建议加大对小微企业和个体工商户的房租、燃气等补贴力度_环球观速讯
- 创业板最新筹码集中股名单(附股)
- CF《穿越火线》王者派对活动什么时候结束_焦点讯息
- 中俄大飞机还没露面,又一款俄机落户太原生产,选中的理由很充分 环球热点评
- 英国政府再次向“全球作战航空计划”拨付资金 环球热讯
- 中牟县自然资源和规划局:积极组织开展世界地球日宣传活动
- 宝马mini被指区别对待中外访客:中国人领冰淇淋时称发完了 外国人领时热情接待-环球时讯
- 今日热文:大地熊: 大地熊2022年年度股东大会决议公告
- 环球微动态丨2023一级建造师《机电工程》每日测试题(04月20日)
- 当前速读:通信自由和通信秘密受法律保护属于我国公民的什么权利(通信自由和通信秘密属于我国公民的什么权利)
- 仙鹤股份:公司目前产销情况稳定正常,经营状况良好,产品订单处于正常状态,产销率稳定
- 观察:美联储褐皮书:经济活跃度几乎不变 信贷量普降
- 2023年高职院校招生就业高峰论坛长沙举办 探讨人才培养新模式_当前独家
- 环球微头条丨华夏人寿为重疾患者撑起“保护伞”
- 高端智能锁第一品牌德施曼以创新技术,开启一场家门口的技术革命!_今日观点
- 当前快播:广西钦州市委书记林冠同志因心源性猝死,经抢救无效逝世
- 每日短讯:白沙县气象台发布雷电黄色预警【Ⅲ级/较重】
- 全球快消息!【国际漫评】山姆大叔正看着你
- 13:19 A股PCB概念股震荡走强,沪电股份涨停_环球快报
- 热讯:浙商智多盈债券增聘基金经理刘新正
- 1只可转债下周上市(4月24日-4月28日) 快看
- 今日热搜:泡沫洗面奶瓶子还能用吗?
- 国家发改委:全面提升长三角产业链供应链韧性和安全水平 速看料
- 顺博合金(002996)4月20日主力资金净卖出914.30万元
- 今日观点!“小法官”零距离学法
- 环球热资讯!黑龙江发布大风预警:局地阵风达10级
- 全球微速讯:子洲县瓜园则湾办事处火石沟村扶贫互助资金协会
- 午评: A股自我强化419九魔咒,今日再次大跌,散户如何对?从容不迫才能穿越牛熊。
- 11部门:今年启动农村产权流转交易规范化试点工作 环球快播报
- 环球新资讯:卫宁健康2022年营收增12%净利降71% 拟10派0.1元
X 关闭