C#一次性对象未被处理,但使用的内存没有增加

本文关键字:内存 增加 对象 一次性 处理 | 更新日期: 2023-09-27 18:24:37

我创建了这个简单的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());
    }
}

C#一次性对象未被处理,但使用的内存没有增加

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

}

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

有各种可能吞噬所有内存,例如

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

如果IDisposable接口实现正确,Finalizer将检查是否已调用Dispose()。否则,终结器将执行此操作。

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

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

这里有一个足够简单的例子,应该不会出现内存不足的问题:

var data = Enumerable.Range(0, int.MaxValue)
    .Select(i => new int[int.MaxValue])
    .ToArray();
Console.WriteLine(data.Length);