我最近继承了一个遇到内存泄漏的asp.net项目。在我的调查中,我注意到有很多实现IDisposable的自定义类,但它们在被调用时并没有使用"using“。我一直在修复这些问题,但我很好奇的一个用例是将静态方法放在类上。如下所示:
public class ImDisposable : IDisposable{
public static GetList(string search){
//doStuff
}
//implement IDisposable
}
public class UseDisposable{
public void GetList(string search){
var list = ImDisposable.GetList(search);
//do stuff
}
}我从来没有见过这样的事情,我很好奇GC是如何处理这种情况的。谢谢。
发布于 2017-11-08 01:16:33
静态方法不依赖于任何特定的实例,因此它们不应该能够访问您的类的实例成员,这可能会占用非托管资源。
在考虑处理资源时,不需要考虑它们。
需要注意的是,方法的存在也与IDisposable没有多大关系。它本身并不处理“方法”,它处理类的实例可能使用的非托管资源。(例如打开的文件流)
发布于 2017-11-08 04:21:07
您可能会混淆内存泄漏和垃圾回收...不调用Dispose()并不意味着会有漏洞。在以下情况下会出现泄漏:
(1)你没有处理的类有一个非托管资源的句柄,例如一个文件流。从理论上讲,如果一个类实现了IDisposable,那么它就拥有非托管资源,但是我已经看到了足够多的空dispose方法,我已经厌倦了。也就是说,对于静态类/成员,除非你有一个需要处理的静态变量,否则这不是你的内存泄漏。
此外,静态成员永远只有一个实例,无论您实例化了多少个类,并且当没有创建新实例时,您不可能真的有泄漏。
(2)当您不需要/不需要时,您可以保留对象引用...事件监听器就是一个很好的例子,尤其是那些作为lambda连接的监听器。不对数据库连接调用Dispose()也被认为是泄漏,即使Dispose()只是将连接返回到连接池。
还要记住,不断增长的内存占用不一定是泄漏。只有当.NET运行时认为有必要时,才会执行垃圾收集...如果仍然有足够的内存可用,就没有必要进行GC。
高度简化的概述;我主要是说没有任何static与您的内存泄漏有关。有一篇关于锁定内存泄漏here的好文章
发布于 2017-11-08 01:37:43
你的问题有点含糊。
您可以参阅Richter的《通过C#进行CLR》一书,了解有关垃圾收集的说明。尽管我的感觉是您的问题更多地是关于非静态类中的静态方法与垃圾收集器之间的交互。上面提到的书也涵盖了这一点。通常,分配资源的静态方法的行为类似于分配资源的非静态方法。但是,IDisposable接口将在类的实例上操作。因此,您的静态GetList(..)方法不应使用需要IDisposable实现才能释放的资源。
https://stackoverflow.com/questions/47163687
复制相似问题