在我的应用程序中,我有一个大对象,每隔几秒钟就创建一次。我做了一些工作,然后我就不需要了。
我在任务管理器中看到,即使我没有对对象的任何引用,并且需要收集它,ram的大小也会增加。
在实现IDisposable之后,ram就会立即下降。
为什么会这样呢?我没有做GC.Collect,我只是发布了这个对象,并告诉GC它不需要为我的对象调用终结器。
编辑:
下面是我为我的IDisposable对象使用的代码:
public void Dispose()
{
base.Dispose();
Dispose(true);
GC.SuppressFinalize();
}
private void Dispose(bool disposing)
{
//here i release unmanaged resources
if (disposing)
{
//here i release all managed resources
}
}
~MyObject()
{
Dispose(false);
}在我的大对象中,我在不再需要它之后做myObject.Dispose();。
我的问题不是如何实现IDisposable或GC一般是如何工作的。我只想知道,当我自己处理对象或让GC完成它的工作时,有什么可能是不同的。
发布于 2012-07-06 09:27:42
正如@Steven在他的评论中指出的那样,IDisposable是CLR不关心的事情。通过实现它,您只需告诉对象的使用者在不再需要对象时调用它的Dispose方法。在mem管理方面,IDisposable2说,您可以为其构建自己的界面,并获得相同的技术效果。但是,这是一件愚蠢的事情,因为当对象不再需要时,.net开发人员应该知道如何调用idisposable.dispose。此外,还内置语言(c#)支持此接口(使用{.})。
你写着“我试着实现IDisposable,然后公羊就完蛋了。”
重要的是你的“工具”是做什么的。那里的代码应该清理非托管代码、windows资源等。
发布于 2012-07-06 09:22:59
对于.NET内存,不像往常一样有两个状态(已使用和未使用),但实际上有4个状态:(A)由活动对象使用,(B)由死对象使用,(C)不被任何对象使用,而是由框架使用,(D)不被使用。
当您创建一个对象时,Framework将首先尝试为它使用类别(C)的内存,因为它没有足够的可用内存,它将要求OS提供一些类型(D),将其转换为(C),然后将其用于对象。
当一个对象超出作用域时,它将从(A)降到(B),在下一次垃圾运行时,它将从(B)降到(C)或(D)。这在很大程度上取决于内部结构(比如记忆碎片和朋友)、内存压力和收集的对象类型(比如IDisposable和朋友)。
你想要实现的是,当你的大对象超出范围后,它所使用的内存会尽快到达(D)。以下是一些提示:
AddMemoryPressure()括号进行实验,但要注意副作用。这类似于强制GC.Collect(),但不太具有侵入性:它将提示GC尽快收集,但不完全now。发布于 2012-07-06 09:51:39
使用IDisposable意味着您正在实现Dispose方法,在该方法中,您将所有清理代码用于不再需要的资源。它不会将对象移到托管堆中,GC仍将负责释放内存。
https://stackoverflow.com/questions/11359131
复制相似问题