排行
数据库百科
核心案例
行业报告
月度解读
大事记
产业图谱
中国数据库
向量数据库
时序数据库
实时数据库
搜索引擎
空间数据库
图数据库
数据仓库
大调查
2021年报告
2022年报告
年度数据库
2020年openGauss
2021年TiDB
2022年PolarDB
2023年OceanBase
首页
资讯
活动
大会
学习
课程中心
推荐优质内容、热门课程
学习路径
预设学习计划、达成学习目标
知识图谱
综合了解技术体系知识点
课程库
快速筛选、搜索相关课程
视频学习
专业视频分享技术知识
电子文档
快速搜索阅览技术文档
文档
问答
服务
智能助手小墨
关于数据库相关的问题,您都可以问我
数据库巡检平台
脚本采集百余项,在线智能分析总结
SQLRUN
在线数据库即时SQL运行平台
数据库实训平台
实操环境、开箱即用、一键连接
数据库管理服务
汇聚顶级数据库专家,具备多数据库运维能力
数据库百科
核心案例
行业报告
月度解读
大事记
产业图谱
我的订单
登录后可立即获得以下权益
免费培训课程
收藏优质文章
疑难问题解答
下载专业文档
签到免费抽奖
提升成长等级
立即登录
登录
注册
登录
注册
首页
资讯
活动
大会
课程
文档
排行
问答
我的订单
首页
专家团队
智能助手
在线工具
SQLRUN
在线数据库即时SQL运行平台
数据库在线实训平台
实操环境、开箱即用、一键连接
AWR分析
上传AWR报告,查看分析结果
SQL格式化
快速格式化绝大多数SQL语句
SQL审核
审核编写规范,提升执行效率
PLSQL解密
解密超4000字符的PL/SQL语句
OraC函数
查询Oracle C 函数的详细描述
智能助手小墨
关于数据库相关的问题,您都可以问我
精选案例
新闻资讯
云市场
登录后可立即获得以下权益
免费培训课程
收藏优质文章
疑难问题解答
下载专业文档
签到免费抽奖
提升成长等级
立即登录
登录
注册
登录
注册
首页
专家团队
智能助手
精选案例
新闻资讯
云市场
微信扫码
复制链接
新浪微博
分享数说
采集到收藏夹
分享到数说
举报
首页
/
LoaRunner性能测试系统学习教程:垃圾收集算法(11)
LoaRunner性能测试系统学习教程:垃圾收集算法(11)
西安川石
2020-12-04
161
点击上方蓝字关注我们
上期我们讲到LoadRunner性能测
GC回收机制
,
这期我们讲LoadRunner性能测试
垃圾收集算法。
垃圾收集算法
上篇文章介绍了GC回收的机制,那么当触发回收机制时,回收垃圾的方法又有哪些呢?这就是本小节要解决的问题,常见的垃圾收集算法包括:标记-清除算法、复制算法、标记-整理算法、分代收集算法。
1)标记-清除算法(Mark-Sweep)
标记-清除算法分为两个阶段完成:标记阶段和清除阶段。标记阶段是将所有需要被回收的对象标记出来,清除阶段就是回收被标记的对象所占用的空间。具体过程如图所示。
标记
-
清除算法是使用
finalize()
方法来进行标记的,从根集合
GC Roots
开始进行扫描,对还存活的对象进行标记,等标记完成后,再重新扫描一次,将未被标记的对象找到并对其进行回收,标记
-
清除算法如图
所示。
使用标记
-
清除算法并不会将对象进行移动,只是对不存活的对象进行处理回收即可,如果处理的对象中存活对象比很高,那么这种方法是很高效的,但是由于不存活的对象可能不是连续的,所以会出现一个问题,会造成内存碎片。
2)复制算法(Copying)
为了解决Mark-Sweep标记-清除算法中关于内存碎片的问题,提出了Copying复制算法,原理是将可用内存划分为大小相等的两块,每次只使用其中的一块,当这块内存使用完成后,就会将还存活的对象复制到另外一块上面,然后把已使用的一块内存清理掉,这样就不会出现Mark-Sweep标记-清除算法内存碎片的问题,如图所示。
复制算法很简单,运行也很高效且不容易产生内存碎片,但前提是以内存为代价,使能够使用的内存缩减到原来的一半。当然复制算法的效率快慢就与存活对象的数目有很大关系了,如果存活的对象很多,那么复制算法的效率就大大的降低了。
复制算法为了解决句柄开销和内存碎片的问题,在一开始就会把堆分成一个对象面和多个空闲面,程序在对象面为工作的对象分配空间,当对象填满后,复制算法的垃圾收集器就从根集合
GC Roots
中扫描活动对象,并将每个活动对象复制到空闲面,这样空闲面变成了对象面,原来的对象面就变成了空闲面,程序会在新的对象面中来分配内存。如图
所示。
3)标记-整理算法(Mark-compact)
复制法牺牲了内存空间,为了解决复制算法的问题,提出了标记-整理算法Mark-Compact算法。该算法与Mark-Sweep有一些相似之处,首先也需要标记对象,但标记完成后不会直接清理可回收的对象,而是将存活的对象都向一端移动,然后清理掉端边界之外的内存。标记-整理算法是在标记-清除算法的基础上,又进行了对象的移动,因此成本更高,但是解决了内存碎片的问题。如图所示。
4)分代收集算法
(GenerationalCollection)
分代收集算法应该是目前用的最多的一种JVM垃圾收集器采用的算法,之所以使用分代收集算法,是因为JVM把内存划分为年轻代、年老代和持久代,如果没有持久代就不用考虑,其中年轻代和年老代是存放在堆中的,因为每个代需要收集的对象有很大不同,使用的频率也有很大不同,所以会对不同代进行不同的回收算法。这种就是通常说的分代收集算法。
分代收集算法其实通常也是使用上面说的三种收集算法,只是在不同的代采用不同的方法来收集而已,对于新生代一般采用的都是复制Copying算法,新生代每次垃圾回收时都会回收了大部分对象,这样复制的操作次数就会少一些,新生代由一块较大的Eden空间和两块小一些的Survivor空间组成,一般每次使用Eden空间和其中的一块Survivor空间,当进行垃圾回收时,会将Eden和Survivor中还存活的对象复制到另一块Survivor空间中,然后将Eden空间和刚才使用过的Survivor空间清理掉。年老代就不可能像年轻代回收的那么频繁,并且每次回收的对象也不会像年轻代那么多,所以年老代一般使用标记-整理Mark-Compact算法。
对于年轻代来说,需要尽快的回收了那些生命周期短的对象,年轻代分为一个eden区和两个survivor区,大部分的对象是在eden区中生成,当GC回收后会将eden区中存活的对象复制到一个survivor0区中,这样eden区就会被清空,当survivor0区都已经存满对象后,就会将对象复制到另外一个survivor1区,再清空eden和这个survivor0区,此时survivor0区是空的,然后将survivor0区和survivor1区交换,即保持survivor1区为空,如此循环。
但当survivor1区不中以存放eden和survivor0的存活对象时,就将存活对象直接放到年老代中,重复这个过程循环后,年老代就可能会存满对象,如果年老代也存满了对象,那么就会触发一次FullGC回收。如果只是年轻代发生GC回收时称之为MinorGC。
如果JVM有持久代的话,持久代也会进行GC回收
但持久代回收的效果并不明显,因为持久代主要用于存放静态文件,如Java类、方法等。
GC有两种类型:ScavengeGC和FullGC。
当新对象生成时,在eden区中申请空间失败时,就会触发ScavengeGC进行回收,ScavengeGC的效率比FullGC高太多了,因为eden区要经常进行回收,所以GC回收的效果一定要高,否则无法进经常回收。
一般情况下,当新对象生成,并且在Eden申请空间失败时
就会触发ScavengeGC,
对Eden区域进行GC
清除非存活对象,并且把尚且存活的对象移动到Survivor区。
然后整理Survivor的两个区。
这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。
因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。
因而,一般在这里需要使用速度快、效率高的算法,使Eden能尽快空闲出来。
由于FullGC回收的内容比较多,所以一般不可能频繁的触发FullGC回收。
一般有以下条件触发时才会触发FullGC回收机制:
1.年老代被写满。
2.持久代被写满。
3.system.gc()被调用。
4.上一次GC后,heap分配的策略发生改变。
完
扫码下面二维码进入软件测试QQ交流群~
扫下方二维码进入腾讯课堂体验免费课程~
关注我们,川石学院带你
玩
转技术!
戳这里,阅读原文
数据库
文章转载自
西安川石
,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
领墨值
有奖问卷
意见反馈
客服小墨