惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Attack and Defense Labs
Attack and Defense Labs
The GitHub Blog
The GitHub Blog
C
Check Point Blog
博客园_首页
MongoDB | Blog
MongoDB | Blog
N
Netflix TechBlog - Medium
F
Full Disclosure
Microsoft Security Blog
Microsoft Security Blog
爱范儿
爱范儿
Recent Announcements
Recent Announcements
阮一峰的网络日志
阮一峰的网络日志
G
GRAHAM CLULEY
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Threat Research - Cisco Blogs
C
Cybersecurity and Infrastructure Security Agency CISA
V
Vulnerabilities – Threatpost
K
Kaspersky official blog
博客园 - 司徒正美
S
Schneier on Security
T
The Exploit Database - CXSecurity.com
Project Zero
Project Zero
云风的 BLOG
云风的 BLOG
Cisco Talos Blog
Cisco Talos Blog
Know Your Adversary
Know Your Adversary
雷峰网
雷峰网
V
V2EX - 技术
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Spread Privacy
Spread Privacy
罗磊的独立博客
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
S
Security Affairs
SecWiki News
SecWiki News
Schneier on Security
Schneier on Security
O
OpenAI News
Jina AI
Jina AI
PCI Perspectives
PCI Perspectives
Cyberwarzone
Cyberwarzone
Y
Y Combinator Blog
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog RSS Feed
I
InfoQ
D
Docker
P
Palo Alto Networks Blog
Recorded Future
Recorded Future
M
MIT News - Artificial intelligence
博客园 - Franky
B
Blog
Scott Helme
Scott Helme
博客园 - 叶小钗
D
DataBreaches.Net

博客园 - Jeri

玩转 H5 下拉上滑动效果 移动H5前端性能优化指南 网站测试清单(转) 分布式缓存概述 SQL循环语句示例 Kconfig文件的作用 转载goahead webserver源码分析 Vista中使用netsh wlan命令行配置无线网络 Linux操作系统下VI编辑器常用命令介绍 - Jeri - 博客园 .net防注入铁盾--亲手教你ASP.NET中如何防止注入攻击 vs2005项模板和项目模板丢失的解决办法(转) Asp.net(c#)导出有表格线的Excel MSSQL如何快速清除数据库日志 数据库查询优化原则(转) 类型或命名空间名称“Web”在类或命名空间“Microsoft”中不存在(是否缺少程序集引用?) 贡献一个新浪的幻灯片(javascript) (转) - Jeri - 博客园 .NET之对接口和抽象类(二) .NET之对接口和抽象类(一) 国外C#开源系统一览表 ,C# Open Source
对.NET的GC(垃圾回收)的理解都存在错误认识
Jeri · 2009-03-11 · via 博客园 - Jeri

  对.NET的GC(垃圾回收)的理解都存在错误。GC其实是相当复杂的系统,虽然95%的情况下我们并不需要考虑它,但仍有5%的情况我们不得不接触GC体系来解决问题。比如这个问题:

void Func()
{
  A a = new A();
  B b = new B();
  a.RefToB = b;
  b.RefToA = a;
}

那么a和b会不会被GC回收?好几个人都答错。如果你按照COM的模式去思考GC,那就完全错误了。每次我问“什么情况下,对象会被GC回收?”,他们都能回答上来“当程序里没有对对象的引用时”。但是错了,为什么?如果你还没明白,就再看看上面这段代码。

GC管理对象不是用的COM的引用计数模式。事实上最初微软确实想用引用计数方式实现GC,这样的一个优势就是对象的析构时机是确定的,当引用计数为0时,对象会被析构,之后也不会再有任何代码能够再访问该对象,这是很理想的情况。但经过反复实验,这种方法被抛弃了。一个原因就是如上的例子,会导致对象无法释放。另一个重要原因就是应用计数的额外开销对高性能程序不可接受。尤其是在多线程情况下,因为.NET使用自由线程模型,多个线程可能同时访问一个对象,每一个引用计数的增减操作都不得不做线程同步。

.NET采用的GC模式是分代GC(Generational GC),堆空间按对象的生存期长短分成4代。新分配的对象在第0代,按地址顺序分配,当第0代的空间(约几百K)用光时,将程序里能引用到的对象移动到第1代,那么剩下的就是垃圾,第0代空间便可以重新用于分配。同理,第1、2代也按同样的逻辑运行,那么第3代里的对象将都是生存期很长的对象。由此可以推出如下几点:
1)对象的分配时间开销远小于C++的堆分配,但回收时间开销大于分配时间开销。
2)不会出现C++里的堆碎片过多的问题,有利于程序长时间运行。
3)循环引用的对象能够被正确回收。

那么再回答开始的问题,“什么情况下,对象会被GC回收?”正确答案是“当程序里没有对对象的活引用(Alive reference)时。”