温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

c#中垃圾回收机制的原理是什么

发布时间:2021-07-07 15:19:15 来源:亿速云 阅读:308 作者:Leah 栏目:大数据

这篇文章给大家介绍c#中垃圾回收机制的原理是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

写了一个window服务,循环更新sqlite记录,内存一点点稳步增长。三天后,内存溢出。于是,我从自己的代码入手,查找到底哪儿占用内存释放不掉,最终明确是调用servicestack.ormlite更新sqlite数据库造成的。至于是不是框架问题,可能性不大,因为本地模拟执行的代码没有任何问题。我觉得应该是orm在执行数据库更新后,对象还在被引用造成的。这里,我贴出一个伪代码:

c#中垃圾回收机制的原理是什么

我的猜测到底对不对呢?现在还不知道。不过在探寻答案的时候,对GC的相关机制详细地了解了一遍。

c#中垃圾回收机制的原理是什么

                                                  图片来源《.NET高级调试》pdf

CLR加载时,就会分配堆。

 三、GC的工作机制

 GC有三个假设:

1、如果没有特别声明,所有的对象都是垃圾(通过引用追踪对象是否为垃圾)

2、假设托管堆上所有的对象的活跃时间都是短暂的(相对于长久活跃的对象来说,GC将更频繁地收集短暂活跃的对象)

3、通过代跟踪对象的持续时间

以下是官方文档给出的和这三个假设一致

The garbage collector in the common language runtime supports object aging using generations

Objects created more recently are part of newer generations, and have lower generation numbers than objects created earlier in the application life cycle. 

Objects in the most recent generation are in generation 0. This implementation of the garbage collector supports three generations of objects, generations 0, 1, and 2

每代都有自己的堆,假如0代的堆满了,就会触发GC,然后把依然有引用的对象升级,放到1代对象。最后压缩堆,把剩余的堆空间合并到一块。1代对象也是如此操作。但到了2代,就处理不同了。2代的堆可能是大对象堆,它的压缩代价过于高昂,所以只是合并相邻的空间。

c#中垃圾回收机制的原理是什么

                                                    图片来源博客园c#技术漫谈之垃圾回收(GC)

Garbage collection happens automatically when a request for memory cannot be satisfied using available free memory

 GC发生的时机,就是相应的堆达到了阈值,因为堆也有大小限制,并不是无限的。尽管2代堆或者大对象堆满的时候,通过增加新的内存段来满足内存分配,如果没有可用的内存,这时就会报内存溢出。

四、GC不能释放非托管资源

有两种情况,第一种:托管代码引用了非托管资源,比如文件操作、数据库连接、网络连接等。这时候必须手动释放,或实现 dispose模式,或实现对象终结

When a type uses unmanaged resources that must be released before instances of the type are reclaimed, the type can implement a finalizer.

In most cases, finalizers are implemented by overriding the Object.Finalize method; however, types written in C# or C++ implement destructors, which compilers turn into an override of Object.Finalize 

必须注意的一点是,实现对象终结器,GC会在释放对象之前自动调用。其实这是一个代价非常高昂的备用机制。所以能自己释放非托管资源的,就自己释放。

如果一个对象中包含有终结器,那么在new的时候放入到终结者队列。当GC会把这个对象标为垃圾时,放入到另一个队列F-Reachable中。这个队列包含了所有带有终结器并且将被作为垃圾收集的对象,这些对象的终结器都将被执行。在垃圾收集的过程总并不会执行终结器代码。而是由.NET 进程的终结线程调用。因此,此时的垃圾回收滞后一段时间,目的在于等待终结器代码执行的完成。

五、dispose模式

c#中垃圾回收机制的原理是什么

关于c#中垃圾回收机制的原理是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI