GC常用算法
一、首先什么是垃圾(garbage)?
没有引用指向的一个或多个对象叫做垃圾;
二、如何找到这些垃圾
一般有两种方法:
-
- 引用计数
- 根可达算法
1、第一种叫做引用计数法(reference count),有一个引用指向一个对象,计数就加1 ,直到这个数为0,就会被当作垃圾。
2、引用计数 不能解决一个问题(循环引用),如果根据引用计数法,这些都不是垃圾,可是没有其他引用指向这一团,那他们就是一团垃圾;那么根可达算法就能够解决,根可达算法的意思就是从根上开始搜索,
当一个程序启动之后马上需要的那些对象就叫做根对象,所谓的Root Searching是首先找到根对象,然后从根对象往下一直找,找到那些被引用的对象。
名词解释:
-
- 根可达算法:从根上对象开始搜索;
- 线程栈变量:一个main方法开始运行,main线程栈中的变量调用了其他方法,main栈中的方法访问到的对象叫根对象;
- 静态变量:T.class对静态变量初始化能够访问到的对象叫做根对象;
- 常量池:如果一个class能够用到其他class对象叫做根对象;
- JNI指针:如果调用了本地方法,本地的对象就叫做根对象;
- 根对象:一个程序启动马上用到的对象叫做根对象
三、GC Algorithms(常见的垃圾回收算法)
GC常用的算法有三个:
-
- Mark-Sweep(标记清除)
- Copying(拷贝)
- Mark-Compact(标记整理)
1、第一个是标记清除,就是把垃圾标记出来,然后把回收对象清理掉,就这么简单,首先找到那些有用的,没有用的标记出来然后清理掉。
标记清除算法有它自己的问题存在,我们从根找到了那些在用不可回收的,然后标记出可以回收的,清除之后就变成了空闲的,这种算法相对简单,在存活对象较多的时候效率比较高,这种算法需要扫描两遍,第一遍是找到那些有用的,第二遍是把那些没有用的找出来然后清理掉,执行效率偏低,容易产生碎片。
2、第二个是复制(Copying)算法,非常简单,就是把内容一分为二,把有用的拷贝到没用的一边,然后把剩下的全部清除,适用于存活对象较少的情况,只扫描一次,效率提高了很多而且没有碎片产生,但是浪费空间,移动复制对象要调整对象的引用。
3、第三个是标记整理(标记压缩)Mark-Compact 就是把所有对象整理的过程,清理的过程同时压缩,有用的全部往前走,剩下的大片空间就清理出来了,空间连续而且没有碎片。
标记整理算法依然有他的问题,在此过程中扫描两次而且还需要移动对象,第一次先找出有用的 第二遍才开始移动,移动过程中如果是多线程还需要进行同步,效率上肯定是降低很多,但是不会产生碎片,方便对象分配,不会产生内存减半。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构