Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何监控C#中的内存泄漏?_C#_Memory Leaks_Out Of Memory - Fatal编程技术网

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

如何监控C#中的内存泄漏?,c#,memory-leaks,out-of-memory,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); } } } 类程序 { 静态void Main(字符串[]参数) { 列表s=新

我正在尝试使用Visual C#进行内存泄漏。我使用了以下代码:

class Program
{
    static void Main(string[] args)
    {
        List<float> s = new List<float>();
        while (true) {
            s.Add(10 ^ 10);
        }
    }
}
类程序
{
静态void Main(字符串[]参数)
{
列表s=新列表();
while(true){
s、 加(10^10);
}
}
}

我运行了这个程序,不到2分钟,我就摆脱了内存异常。这是内存泄漏的真实代码吗?我在监视主内存空间,它有足够的空间。若这是内存泄漏,那个么哪一个导致这个内存泄漏,即使ram中有空间?如何监视此泄漏?

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

有可能你正在打


垃圾收集器将确保在不再引用对象时释放与该对象关联的内存。

您希望
s.Add
做什么?每次执行时,它都会在列表中添加一个新元素。因此,第一次,你将有一个包含一个元素的列表,第二次
s
现在是一个包含两个元素的列表,第一百万次它将包含一百万个元素。它将一直这样运行,直到它太大而无法装入内存。

您的示例不是内存泄漏,您将耗尽内存,但运行的程序可以访问您创建的所有对象。泄漏是指内存中存在无法访问的对象。下面是导致.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){}
    }

}

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

您误解了内存泄漏和内存不足。内存不足可能是内存泄漏的一种症状,但它们不是一回事。我建议你仔细阅读这两篇文章,这样你就能理解其中的区别。以上评论是100%正确的。这是一种创建内存不足场景的方法,技术上也不是泄漏。您可以编写一些代码来执行:
SomeStaticEvent=null
从而允许释放所有
A
对象。是的,您可以,但如果不这样做怎么办。你可以(也应该)取消订阅aviod leak。。正如我所看到的,当你没有做你应该做的事情时,总是会发生泄漏。根据这个定义,OP的代码确实是一个泄漏,因为如果他做了什么事情,内存可以被回收。有些人选择使用这个定义(特别是在C#中),如果他们清楚的话,这是可以的,但是使用这个定义你的代码和OP的代码没有什么不同。然而,在C/C++中,内存泄漏被称为丢失了对对象的所有引用,但没有回收其内存。当这种情况发生时,你就失去了收回它的能力。我明白你的意思,我同意。但是C++是不同的,你必须调用析构函数,程序员负责内存的分配。在.NET中,我们确实有GC。这可能不是“真正的”泄漏,但根据我的经验,这是在内存中保留“超出范围”对象的常见情况。我在很多库中都看到了这个“bug”,即使是最有经验的团队创建的库。不管你叫不叫它泄漏,你丢失了内存,如果没有一些你不需要做的黑客攻击,你就无法恢复。谢谢你们的回复。我用C/C++编写了带有指针示例的代码,也用C#编写了代码。没有,我发现了错误。我一直在关注记忆的表现,但这对我来说似乎还行。若内存泄漏意味着程序不能释放对象空间,那个么我的程序也在这样做。我发现,无论我添加什么,错误都发生在相同的列表计数xxxxxxxxx(9位)计数上。是的,你说得对。我想让我的内存满,直到我有内存泄漏。事实上,这就是我所期望的。但事实并非如此。看起来,我仍然有内存,但.NET停止在列表中添加更多元素。列表计数一直到9位数。