c# 垃圾回收gc原理

发布时间 - 2026-01-03 00:00:00    点击率:
GC是按需触发的标记-压缩回收机制,非定时执行;.NET分代回收通过对象存活次数动态晋升,90%对象死于Gen 0;标记-清除-压缩三步确保高效分配,但LOH不压缩易碎片化;手动调用GC.Collect()几乎总是错误。

GC 不是“定时扫垃圾”,而是“按需暂停+标记压缩”——它只在内存分配失败、系统压力大或显式调用时才启动,且每次回收都伴随短暂的 Stop-The-World(STW)暂停。理解这点,才能避开“为什么用了 GC.Collect() 反而更卡”这类误区。

分代回收不是分类管理,而是性能优化的核心策略

.NET 把托管堆划为三代(Gen 0Gen 1Gen 2),但这个划分不是静态标签,而是对象存活次数的动态记录:

  • new 出来的对象默认进 Gen 0
  • 一次 Gen 0 GC 后还活着,就升到 Gen 1
  • 再活过一次 Gen 1 GC,就进 Gen 2
  • Gen 2 对象基本不挪动,除非触发全堆回收(Full GC)。

关键点:90% 的对象死在 Gen 0,所以 GC 大部分时间只扫描几 MB 内存,极快。一旦你把短期对象(比如循环里的 byte[1024])长期持有(例如塞进静态 List),它就会不断晋升,最终拖慢 Gen 2 回收——这是最常见性能拐点。

标记-清除-压缩三步缺一不可,但压缩只对小对象生效

GC 不是简单删掉对象就完事。它必须保证后续分配还能用“指针碰撞”(Bump Pointer)这种 O(1) 速度分配新对象,所以压缩必不可少:

  • 标记阶段:从根(静态字段、栈变量、寄存器等)出发,递归标记所有可达对象;
  • 清除阶段:释放未被标记的内存块;
  • 压缩阶段:仅对 Gen 0Gen 1 中的小对象堆(SOH)执行——把存活对象往低地址挤,腾出连续空闲空间;
  • 大对象堆(LOH)不压缩:>85,000 字节的对象(如大数组)直接进 LOH,GC 清理后只链表记录空闲块,不移动。久而久之就碎片化,可能提前触发 Full GC。

这就是为什么反复 new byte[100000]new byte[1000] 更容易引发卡顿——前者直奔 LOH,后者还在 SOH 里被快速回收。

手动调用 GC.Collect() 几乎总是错的

CLR 的 GC 调度器比你更懂当前内存状态。强行调用只会:

  • 打断正在运行的后台 GC(Server GC 模式下);
  • 强制升级本可留在 Gen 0 的对象;
  • 引发不必要的 STW 暂停,尤其在 UI 线程调用时直接卡界面;
  • 掩盖真正问题:比如事件没解绑、缓存没清理、IDisposable 没用 using

唯一合理场景:进程即将退出,或长时间后台任务结束前想主动释放一批大资源(仍建议只指定 GC.Collect(0),避免触碰 Gen 2)。

真正该盯住的不是 GC 本身,而是对象生命周期——谁在持有着不该持有的引用?静态集合是否在无限增长?Finalizer 是否在阻塞终结队列?这些才是 GC 表现异常背后的实锤线索。


# 字节  #   # c#  # .net  # 为什么  # 递归  # 循环  # 指针  #   # using  # 线程  # pointer  # 对象  # 事件  # 性能优化  # ui  # 三步  # 按需  # 这是  # 就会  # 还在  # 才是  # 这就是  # 长时间  # 只会 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: phpredis提高消息队列的实时性方法(推荐)  详解jQuery中的事件  Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】  免费视频制作网站,更新又快又好的免费电影网站?  Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】  Laravel如何实现模型的全局作用域?(Global Scope示例)  googleplay官方入口在哪里_Google Play官方商店快速入口指南  微信小程序 wx.uploadFile无法上传解决办法  Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程  Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】  如何用PHP快速搭建CMS系统?  简历在线制作网站免费版,如何创建个人简历?  Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】  如何在服务器上三步完成建站并提升流量?  电商网站制作价格怎么算,网上拍卖流程以及规则?  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  七夕网站制作视频,七夕大促活动怎么报名?  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?  Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用  Laravel如何实现本地化和多语言支持?(i18n教程)  如何构建满足综合性能需求的优质建站方案?  php json中文编码为null的解决办法  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】  原生JS实现图片轮播切换效果  如何在建站之星绑定自定义域名?  Laravel如何使用Laravel Vite编译前端_Laravel10以上版本前端静态资源管理【教程】  如何快速搭建高效可靠的建站解决方案?  高防服务器如何保障网站安全无虞?  Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程  如何用JavaScript实现文本编辑器_光标和选区怎么处理  弹幕视频网站制作教程下载,弹幕视频网站是什么意思?  高性能网站服务器部署指南:稳定运行与安全配置优化方案  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  安克发布新款氮化镓充电宝:体积缩小 30%,支持 200W 输出  香港服务器建站指南:外贸独立站搭建与跨境电商配置流程  如何用美橙互联一键搭建多站合一网站?  Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能  实例解析Array和String方法  三星、SK海力士获美批准:可向中国出口芯片制造设备  javascript中对象的定义、使用以及对象和原型链操作小结  如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?  Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】  魔毅自助建站系统:模板定制与SEO优化一键生成指南  Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)  北京的网站制作公司有哪些,哪个视频网站最好?  如何在云指建站中生成FTP站点?