在C#中强制删除/处理
本文关键字:删除 处理 | 更新日期: 2023-09-27 17:51:14
我从来没有真正想到过这一点,因为当我从C++迁移到C#时,我从来没有考虑过它,但是。。。有没有一种方法可以强制释放内存,比如List
、数组,甚至是不实现IDisposable
的对象?让我解释一下我的想法。。。
在C++中,如果我想创建一个动态数组,我会写这样的东西:
int* arr = NULL;
arr = new int[10];
然而,我必须在完成后删除它,否则就会出现内存泄漏:
delete [] arr;
嗯,在C#中似乎没有类似的东西,或者有吗?我一直找不到。似乎只有实现IDisposable
接口的对象才能被强制释放。那么,设定是说。。。数组转换为null
,在这种情况下让GC清理内存是唯一的方法吗?
我读过GC.Collect()
,强迫早期收集是不受欢迎的,所以我想知道这些类型是否有什么奇怪的地方?我意识到C#不是C++,我只是想知道我是否遗漏了一些显而易见的东西。
设置说。。。数组转换为
null
,让GC清理是在这种情况下清理内存的唯一方法
好吧,第一位可能是错误的,除非arr
实际上(比如(是另一个将继续存在很长一段时间的对象的字段。在您的示例中,arr
是一个局部变量,GC和JIT协同(当您运行发布代码时,而不是调试(可以非常准确地知道这些变量的生存期。他们知道arr
不再使用,因此有资格进行垃圾收集-无需将null
分配给它。
现在,对于更广泛的问题——不,没有办法急切地把记忆交回来。实际上,让你告诉GC"请现在收回这个内存块"是更多的工作1。正如你所说,GC.Collect
是不受欢迎的,因为即使这样也不是真正的"请收回我不再使用的内存块",而是"请运行您的完整分析,以确定不再需要的所有内存块,然后执行压缩等"。
1托管内存系统有一种简单的方法来跟踪新分配的可用内存——它位于所有先前分配块的末尾。因此,压缩是可以重用已释放内存的唯一方法。
不,中没有释放单个托管对象使用的内存的现有方法。网
你可以选择
- 自己管理本机内存(即GlobalAloc函数的PInvoke(
- 在释放对特定托管对象的所有非弱引用后强制完成垃圾收集(
GC.Collect();GC.WaitForPendginFinalizers()
IDisposable
接口的类实现方法Dispose
,该方法用于强制处理对象。
但是C#中有一个垃圾回收器,它会自动删除所有未被引用的对象。这意味着当你离开它的上下文等时,所有的局部变量都会自动删除。
所以在很多情况下,调用Dispose
是不必要的。。。
一般来说,如果你想在使用后释放对象的内存,我建议使用using
语句:
using (... some object creation ...)
{
... using object ...
}
// here, the object is disposed