相关疑难解决方法(0)

正确使用IDisposable接口

我从阅读MSDN文档中了解到,IDisposable接口的"主要"用途是清理非托管资源.

对我来说,"非托管"意味着数据库连接,套接字,窗口句柄等等.但是,我已经看到了Dispose()实现该方法以释放托管资源的代码,这对我来说似乎是多余的,因为垃圾收集器应该照顾那对你而言.

例如:

public class MyCollection : IDisposable
{
    private List<String> _theList = new List<String>();
    private Dictionary<String, Point> _theDict = new Dictionary<String, Point>();

    // Die, clear it up! (free unmanaged resources)
    public void Dispose()
    {
        _theList.clear();
        _theDict.clear();
        _theList = null;
        _theDict = null;
    }
Run Code Online (Sandbox Code Playgroud)

我的问题是,这是否使得垃圾收集器可以使用的内存MyCollection比通常更快?

编辑:到目前为止,人们已经发布了一些使用IDisposable清理非托管资源(例如数据库连接和位图)的好例子.但是假设_theList在上面的代码中包含了一百万个字符串,并且你想现在释放那个内存,而不是等待垃圾收集器.上面的代码会实现吗?

.net c# garbage-collection idisposable

1586
推荐指数
12
解决办法
31万
查看次数

为什么垃圾收集者在解除分配之前会等待?

我有一个"为什么这样做?" 关于垃圾收集的问题(任何/所有实现:Java,Python,CLR等).当垃圾收集器不再处于任何范围内时,它会释放该对象; 指向它的引用数为零.在我看来,一旦引用数量达到零,框架就可以解除分配,但我遇到的所有实现都会等待一段时间,然后一次解除分配许多对象.我的问题是,为什么?

我假设框架为每个对象保留一个整数(我认为Python会这样做,因为你必须调用PyINCREFPyDECREF在C中为它编写扩展模块时;可能这些函数在某处修改了一个真正的计数器).如果是这样,那么它不应该花费更多的CPU时间来消除对象超出范围的时刻.如果现在每个对象需要x纳秒,那么以后每个对象需要x纳秒,对吗?

如果我的假设是错误的并且没有与每个对象关联的整数,那么我理解为什么垃圾收集等待:它必须走引用图以确定每个对象的状态,并且该计算需要时间.这样的方法比显式引用计数方法消耗更少的内存,但我很惊讶它更快或者是其他原因的首选方法.这听起来像是很多工作.

从编程的角度来看,如果对象在超出范围后立即释放,那将会很好.我们不仅可以依赖于在我们希望它们执行时执行的析构函数(其中一个Python陷阱是__del__在可预测的时间没有调用),但是对程序进行内存配置会变得更加容易. 这是一个由此引起的混淆的例子.在我看来,在deallocate-right-away框架中编程的好处是如此之大,以至于为什么我所听到的所有实现在解除分配之前都要等待.这有什么好处?

注意:如果遍历引用图只需要识别循环引用(纯引用计数不能),那么为什么不采用混合方法呢?一旦引用计数达到零,就释放对象,然后进行定期扫描以查找循环引用.在这样的框架中工作的程序员将有一个性能/决定论理由,尽可能地坚持非循环引用.它通常是可行的(例如,所有数据都是JSON对象的形式,没有父指针).这是流行垃圾收集器的工作原理吗?

garbage-collection reference-counting

18
推荐指数
3
解决办法
2498
查看次数