如何监控C#中的内存泄漏?

时间:2013-05-01 16:35:28

标签: c# memory-leaks out-of-memory

我正在尝试做内存泄漏Visual C#。我用过这个代码:

class Program
{
    static void Main(string[] args)
    {
        List<float> s = new List<float>();
        while (true) {
            s.Add(10 ^ 10);
        }
    }
}

我跑了这个程序,在2分钟内,我得到了OutofMemory异常。这是内存泄漏的真实代码吗?我正在监视主内存空间,它有足够的空间。如果这是内存泄漏,那么即使在ram中有空间,也会导致这个内存泄漏?我该如何监控此泄漏?

3 个答案:

答案 0 :(得分:5)

这不是内存泄漏。您添加的每个号码仍可从列表对象访问。你的代码只是占用了大量内存,最终耗尽了。

你可能正在点击the maximum amount of memory for a single object

当没有对该对象的引用时,垃圾收集器将确保释放与对象关联的内存。

答案 1 :(得分:2)

您的示例不是内存泄漏,您将耗尽内存,但正在运行的程序可以加入您创建的所有目标。泄漏是指内存中无法访问的目标。下面是一个可能是.NET中最常见的泄漏原因的例子,订阅静态事件:

internal class Program
{
    public static event EventHandler SomeStaticEvent;

    private static void Main()
    {
        while (true)
        {
            var a = new A();                

            //here a goes out of scope but won't be collected by GC because Program still holds reference to "a" by a static event subsription
        }
    }      
    public class A
    {                       
        public A()
        {
            //if you comment this line, there is no reference from Program to A and a will be GC-ed and memory allocated will be released
            Program.SomeStaticEvent+=ProgramOnSomeStaticEvent;
        }
        private void ProgramOnSomeStaticEvent(object sender, EventArgs eventArg){}
    }

}

小心订阅静态事件或长生命对象的事件。你的程序正在泄漏,并不容易发现原因。在对象超出范围之前,始终取消订阅此类事件。

答案 2 :(得分:1)

您期望s.Add做什么?每次执行时,它都会在列表中添加一个新元素。所以第一次,你将有一个包含一个元素的列表,第二次s现在是一个包含2个元素的列表,第百万次它将拥有一百万个元素。它会继续这样,直到它太大而不适合记忆。