C# GC内存泄漏

本文探讨了C#中的两种内存泄漏类型:狭义和广义。狭义内存泄漏涉及静态对象未释放和事件监听器导致的问题,如静态字段过度使用、未正确清理事件监听者和闭包引起的内存占用。广义内存泄漏主要指非托管类型的内存管理,通过实现IDisposable接口进行清理。文章还提到终结器的风险,并通过示例代码分析了终结器执行的异常情况,建议使用IDisposable确保资源释放。
摘要由CSDN通过智能技术生成

暂时写下我现在知道的,以后有更深的理解再补充,写的不对的欢迎留言指出。

查了一些资料,GC内存泄漏我觉得可以分为狭义的内存泄漏和广义的内存泄漏吧,狭义的泄漏是因为某些认为原因,GC未能履行其职责清除内存,比如编码的时候不小心忘记清除没用的静态共有对象,使得他一直占有没用内存。广义的泄漏就是真的就泄漏了,主要是非托管类型。

对于第一种情况我知道的几种泄漏的方式:

1、静态对象没有及时释放。静态对象在程序运行期间都占据内存。这个怎么说,我觉得除了一些工具类和管理器其他部分应该尽量避免静态字段吧,如果模块间要通过静态字段通讯,那耦合度肯定是有点高的。

2、事件。之前实习过看到框架各种OnDisable清除事件内的监听者,那时候可能搜索的姿势不对查不到什么资料,现在终于是明白了。事件导致的内存泄漏可以看一下这种情况:在函数中给全局事件添加一个监听者,甚至还引用了函数内的局部变量,因为C#中有闭包的机制,所以这个本应该在函数结束就被清除的局部变量会被写入监听者内部,也就是他是一直被引用了,如果忘记清除事件,这个引用将一直存在,导致所谓的内存泄漏。

3、多线程。每个线程分配了私有栈和内核栈,就算不用也是占据内存的。多线程的泄漏可以是开了一个无限运行的线程而且忘了关闭,自身堆栈占据内存,甚至线程可能是一个用来处理独立事件的线程,比如点击事件,每点击一次如果需要开启新的线程或者定义一些新的对象来存储数据,那么这个不仅是泄漏,而且泄漏的内存还会随点击的次数慢慢增大。

对于第二种情况:

主要是非托管类型,非托管类型可以通过实现IDisposable接口清除,如果使用终结器清除是有风险的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值