0

我创建了这个简单的 C# 程序,期望它抛出 OutOfMemoryException。问题是它可以在不使用我所有笔记本电脑内存的情况下完美运行。为什么?我怎样才能让它泄漏所有的内存?

static void Main(string[] args)
{
    for (int i = 0; true; i++)
    {
        new MustDispose();
    }
}


class MustDispose
{
    public MustDispose()
    {
        StreamReader r = null;
        r = File.OpenText("C:\\Users\\rverdelli\\Desktop\\asd.txt");
        if (r.EndOfStream) return;
        Console.WriteLine(r.ReadToEnd());
    }

}
4

2 回答 2

3

循环的每次迭代都不会存储超出该迭代范围的任何状态,因此当它结束时,可以释放该迭代中分配的所有内存。

如果你想用完内存,你需要保留你正在分配的内存。

这是一个足够简单的示例,应该不会让您内存不足:

var data = Enumerable.Range(0, int.MaxValue)
    .Select(i => new int[int.MaxValue])
    .ToArray();
Console.WriteLine(data.Length);
于 2014-09-26T16:07:11.797 回答
3

在您的方法MustDispose()中,有一个很重要的字符:

}

这定义了范围的结束,这意味着局部变量不再有效。不再有效告诉垃圾收集器删除局部变量,尤其r是所有尚未分配给变量的临时结果(即布尔返回值r.EndOfStream和字符串r.ReadToEnd())。

吃掉所有记忆的可能性有很多种,例如

var keeper = new List<byte[]>();
while(true)
{
    keeper.Add(new byte[1024*1024]);
}

如果IDisposable 接口被正确实现,Finalizer 将检查 Dispose() 是否已经被调用。如果没有,Finalizer 会这样做。

于 2014-09-26T16:10:07.110 回答