当我们进行垃圾回收的时候,首先需要判断哪些对象是存活的?
常用的方法有如下两种
Python判断对象存活的算法用的是引用计数法,而Java则使用的是可达性分析法。
「通过GC ROOT可达的对象,不能被回收,不可达的对象则可以被回收,搜索走过的路径叫做引用链」
不可达对象会进行2次标记的过程,通过GC ROOT不可达,会被第一次标记。如果需要执行finalize()方法,则这个对象会被放入一个队列中执行finalize(),如果在finalize()方法中成功和引用链上的其他对象关联,则会被移除可回收对象集合(「一般你不建议你使用finalize方法」),否则被回收
「常见的GC ROOT有如下几种」
「照这样看,程序中的GC ROOT有很多,每次垃圾回收都要对GC ROOT的引用链分析一遍,感觉耗费的时间很长啊,有没有可能减少每次扫描的GC ROOT?」
其实当前虚拟机大多数都遵循了“分代收集”理论进行设计,它的实现基于2个分代假说之上
因此堆一般被分为新生代和老年代,针对新生代的GC叫MinorGC,针对老年代的GC叫OldGC。但是分代后有一个问题,为了找到新生代的存活对象,不得不遍历老年代,反过来也一样 当进行MinorGC的时候,如果我们只遍历新生代,那么可以判定ABCD为存活对象。但是E不会被判断为存活对象,所以就会有问题。
为了解决这种跨代引用的对象,最笨的办法就是遍历老年代的对象,找出这些跨代引用的对象。但这种方式对性能影响较大
这时就不得不提到第三个假说
「跨代引用相对于同代引用来说仅占极少数。」
根据这条假说,我们就不需要为了少量的跨代引用去扫描整个老年代。「为了避免遍历老年代的性能开销,垃圾回收器会引入一种记忆集的技术,记忆集就是用来记录跨代引用的表」
如新生代的记忆集就保存了老年代持有新生代的引用关系
所以在进行MinorGC的时候,只需要将包含跨代引用的内存区域加入GC ROOT一起扫描就行了
前面我们说到垃圾收集器用记忆集来记录跨代引用。其实你可以把记忆集理解为接口,卡表理解为实现,类比Map和HashMap。
卡表最简单的形式可以只是一个字节数组, 而HotSpot虚拟机确实也是这样做的。以下这行代码是HotSpot默认的卡表标记逻辑:
CARD_TABLE [this address >> 9] = 0;
HotSpot用一个数组元素来保存对应的内存地址是有有跨代引用对象(从this address右移9位可以看出每个元素映射了512字节的内存)
当数组元素值为0时表明对应的内存地址不存在跨代引用对象,否则存在(称为卡表中这个元素变脏)
「将卡表元素变脏的过程,HotSpot是通过写屏障来实现的」,即当其他代对象引用当前分代对象的时候,在引用赋值阶段更新卡表,具体实现方式类似于AOP
void oop_field_store(oop* field, oop new_value) {
// 引用字段赋值操作
*field = new_value;
// 写后屏障,在这里完成卡表状态更新
post_write_barrier(field, new_value);
}
「如何判断一个对象可达呢?这就不得不提到三色标记法」
白色:刚开始遍历的时候所有对象都是白色的 灰色:被垃圾回收器访问过,但至少还有一个引用未被访问 黑色:被垃圾回收器访问过,并且这个对象的所有引用都被访问过,是安全存活的对象(GC ROOT会被标记为黑色)
以上图为例,三色标记法的执行流程如下
可达性分析算法根节点枚举这一步必须要在一个能保障一致性的快照中分析,所以要暂停用户线程(Stop The World ,STW),在各种优化技巧的加持下,停顿时间已经非常短了。
在从根节点扫描的过程则不需要STW,但是也会发生一些问题。由于此时垃圾回收线程和用户线程一直运行,所以引用关系会发生变化
第一种情况影响不大,大不了后续回收即可。但是第二种情况则会造成致命错误
所以经过研究表明,只有同时满足两个条件才会发生第二种情况
为了解决这个问题,我们破坏2个条件中任意一个不就行了,由此产生了2中解决方案,「增量更新」和「原始快照」。CMS使用的是增量更新,G1使用的是原始快照
「增量更新要破坏的是第一个条件」, 当黑色对象插入新的指向白色对象的引用关系时, 就将这个新插入的引用记录下来, 等并发扫描结束之后, 再将这些记录过的引用关系中的黑色对象为根, 重新扫描一次。这可以简化理解为, 黑色对象一旦新插入了指向白色对象的引用之后, 它就变回灰色对象了
「原始快照要破坏的是第二个条件」, 当灰色对象要删除指向白色对象的引用关系时, 就将这个要删除的引用记录下来, 在并发扫描结束之后, 再将这些记录过的引用关系中的灰色对象为根, 重新扫描一次。这也可以简化理解为, 无论引用关系删除与否, 都会按照刚刚开始扫描那一刻的对象图快照来进行搜索。
参考自《深入理解Java虚拟机》
图中展示了七种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用。在JDK8时将Serial+CMS,ParNew+Serial Old这两个组合声明为废弃,并在JDK9中完全取消了这些组合的支持
并行和并发都是并发编程中的专业名词,在谈论垃圾收集器的上下文语境中, 它们可以理解为
「并行(Parallel)」:指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态
「并发(Concurrent」):指用户线程与垃圾收集线程同时执行
「新生代,标记-复制算法,单线程。进行垃圾收集时,必须暂停其他所有工作线程,直到它收集结束」
「ParNew本质上是Serial收集器的多线程并行版本」
「新生代,标记复制算法,多线程,主要关注吞吐量」
吞吐量=运行用户代码时间/(运行用户代码时间+运行垃圾收集时间)
「老年代,标记-整理算法,单线程,是Serial收集器的老年代版本」
用处有如下2个
「老年代,标记-整理算法,多线程,是Parallel Scavenge收集器的老年代版本」
在注重吞吐量或者处理器资源较为稀缺的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器这个组合
「老年代,标记-清除算法,多线程,主要关注延迟」
运作过程分为4个步骤
收集器 | 收集对象和算法 | 收集器类型 | 说明 | 适用场景 |
---|---|---|---|---|
Serial | 新生代,复制算法 | 单线程 | 简单高效;适合内存不大的情况 | |
ParNew | 新生代,复制算法 | 并行的多线程收集器 | ParNew垃圾收集器是Serial收集器的多线程版本 | 搭配CMS垃圾回收器的首选 |
Parallel Scavenge吞吐量优先收集器 | 新生代,复制算法 | 并行的多线程收集器 | 类似ParNew,更加关注吞吐量,达到一个可控制的吞吐量 | 本身是Server级别多CPU机器上的默认GC方式,主要适合后台运算不需要太多交互的任务 |
收集器 | 收集对象和算法 | 收集器类型 | 说明 | 适用场景 |
---|---|---|---|---|
Serial Old | 老年代,标记整理算法 | 单线程 | Client模式下虚拟机使用 | |
Parallel Old | 老年代,标记整理算法 | 并行的多线程收集器 | Paraller Scavenge收集器的老年代版本,为了配置Parallel Svavenge的面向吞吐量的特性而开发的对应组合 | 在注重吞吐量以及CPU资源敏感的场合采用 |
CMS | 老年代,标记清除算法 | 并行与并发收集器 | 尽可能的缩短垃圾收集时用户线程停止时间;缺点在于,1.内存碎片,2.需要更多CPU资源,3.浮动垃圾问题,需要更大的堆空间 | 重视服务的相应速度,系统停顿时间和用户体验的互联网网站或者B/S系统。互联网后端目前cms是主流的垃圾回收器 |
G1 | 跨新生代和老年代;标记整理+化整为零 | 并行与并发收集器 | JDK1.7才正式引入,采用分区回收的思维,基本不牺牲吞吐量的前提下完成低停顿的内存回收;可预测的停顿是其最大的优势 |
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/AdF--fvDq63z0Inr2-JSHw
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。