我想使用C#创建内存泄漏,所以我编写以下代码尝试创建一个。这个概念是编写一个显式的Dispose,除了调用GC.SuppressFinalize()之外什么都不做,以防止GC的工作。但是当我运行代码时,内存并没有泄漏。任何人都可以帮忙告诉我为什么?
class Program
{
static void Main(string[] args)
{
while (true)
{
var t = new Foo();
t.create_leak();
t.Dispose();
}
}
}
class Foo:IDisposable
{
public void create_leak() {
m_value = new int[10000];
Console.WriteLine(m_value[10].ToString()+DateTime.Now.ToString());
}
public void Dispose() { GC.SuppressFinalize(this); }
private int[] m_value;
~Foo() { }
}
答案 0 :(得分:3)
这个概念是编写一个显式的Dispose,除了调用GC.SuppressFinalize()之外什么也不做,以防止GC的工作。
GC.SuppressFinalize
不会阻止GC的工作。它只是阻止GC调用对象的终结器。但是,托管内存仍将被收回。如果要创建内存泄漏,则需要分配非托管内存或以无法回收的方式分配托管内存(因为它仍将无限期地引用)。 String interning就是这样的一种方式。编译的正则表达式是另一个(但是,当您的进程终止时,该内存当然仍将被回收)。
答案 1 :(得分:3)
这不是泄漏,因为每个Foo
仍然有资格在每个循环结束时收集; SuppressFinalize
只表示不会调用~Foo()
- 它不会改变每个m_value
都有资格收集的事实。
很难获得真正的泄密。如果您只想填充内存,请将所有Foo
实例保留在List<T>
或类似内容中 - 那么它们将永远不会有资格收集。对于真正的泄漏,您可能希望分配非托管内存 - 可能是Marshal.AllocHGlobal
。
答案 2 :(得分:0)
我建议您使用“Bitmaps”或“Fonts”等对象来生成内存泄漏。这些对象要求您明确处置它,否则可能导致内存泄漏。可以在这里找到一个例子: