常用的垃圾回收算法标记-清除标记清除算法是一种非移动式的回收算法,分为标记
清除
2个阶段,简而言之就是先标记出需要回收的对象,标记完成后再回收掉所有标记的内存对象,如下图
【java中的垃圾回收算法与垃圾回收器】
文章插图
可见回收后图中被标记的对象被删除回收了,但是碎片化比较严重不连续 对于下次分配大对象的时候由于内存不连续性影响比较大,而且每一次Gc的时候需要执行2个操作 1次标记 1次回收
标记-整理压缩标记整理压缩算法是一种移动式的算法,由于上面标记清除算法导致内存不连续的问题 标记-整理算法就解决了这个问题 。
文章插图
工作原理也是2阶段操作而且更复杂了,首先找出(root)根地址的对象一直寻找标记是否被引用,引用了就标记一下 , 标记完成后把标记的对象按顺序移动排列在一起并清除掉边界的未标记的对象 , 这样就没有内存碎片 。
缺点
- 由于标记完成后需要移动对象 移动的过程可能会产生STW
- 2次+调整指针
文章插图
分代回收算法根据对象的存活周期划分为新生代、老年代 。因此可以根据不同年代的特点使用不同的回收算法 。分代收集目前是大部分JVM
- 新生代特点
在新生代中大量的对象产生 又有大量的对象需要销毁,他们存活时间都比较短 。基本上都是回收的时候大部分会被回收掉,只有少量的对象是存活不回收的 。
存活对象少,垃圾对象多这就比较适合使用复制算法,复制算法需要用到2块内存空间 每次只使用其中一块 , 在jdk8中不只是单纯的划分为s0
s1
二块存储空间 , 还新增了一块Eden
,s0 s1的默认大小是eden的8/1 这样设计的目的在于每次触发回收的时候把90(eden+其中1个s区)的区域中存活的对象copy到10%的存储中 , 理论上清除了90%的空间 , 这样做的好处就是不需要花50%的存储空间,只浪费了10%的空间就实现了这个算法逻辑 。
- 老年代特点
老年代的特点就是对象存活时间都比较长 , 大量的存活对象就不适合像新生代一样用复制算法了 因为copy的成本太高 , 这种就比较适合标记清除算法,或者标记清除整理算法 。
优缺点概述
算法名称优点缺点标记-清除简单位置不联系 碎片化严重 效率低 2次扫描标记-压缩整理没有碎片效率低 2次扫描 可能会多次重置指针复制算法没有碎片 简单高效浪费空间
文章插图
文章插图
serial串行收集器serial回收器是一个串行单线程回收器 , 在进行垃圾回收的时候必须暂停用户工作线程,直到回收线程处理完成,每次回收必然会STW 。比较适合跑在client端应用
文章插图
ParNew收集器ParNew回收器是
新生代
垃圾回收器, 就是serial的多线程版本 其它基本上serial差不多的,在ps回收器没有出来之前parNew+cms是服务器端首选文章插图
Parallel Scavenge收集器常说的
ps
收集器就算它,ps是一个新生代收集器采用复制算法,多线程并行收集 。是jdk8的默认新生代回收器 。看起来和parNew有点一样 反正性能就是比它要强,在应用吞吐量方面更优秀 。ps一般是和Parallel Old配合使用
推荐阅读
- 我终于会写 Java 的定时任务了!
- Java 8 Stream API 引入和使用
- JUC中的AQS底层详细超详解
- Java并发编程 | Synchronized原理与使用
- javascript编程单线程之同步模式
- java程序员在交接别人的工作时如何保证顺利交接?
- Briefings in Bioinformatics-2021 知识图谱-生物信息学-医学顶刊论文:生物信息学中的图表示学习:趋势、方法和应用
- 都卷Java,你看看你得学多少技术栈才能工作!
- golang中的nil接收器
- JavaScript函数式编程之函子