Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.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_Memory Leaks - Fatal编程技术网

c#:模拟内存泄漏

c#:模拟内存泄漏,c#,memory,memory-leaks,C#,Memory,Memory Leaks,我想用c#编写以下代码。 a) 模拟内存泄漏的小型控制台应用程序。 b) 调用上述应用程序并立即释放的小型控制台应用程序,模拟管理内存泄漏问题 换句话说,(b)应用程序将不断调用并释放应用程序(a),以模拟如何在不解决根本原因(即应用程序(a))的情况下包含“叛逆”内存泄漏应用程序 应用程序(a)和(b)的一些示例代码将非常有用 感谢您,只需将对象添加到计时器上的全局列表中,您就可以模拟内存泄漏。只需创建IDisposable对象,而不要处置它们!示例包括图像图形或任何类型的句柄或代码,这些句柄

我想用c#编写以下代码。 a) 模拟内存泄漏的小型控制台应用程序。 b) 调用上述应用程序并立即释放的小型控制台应用程序,模拟管理内存泄漏问题

换句话说,(b)应用程序将不断调用并释放应用程序(a),以模拟如何在不解决根本原因(即应用程序(a))的情况下包含“叛逆”内存泄漏应用程序

应用程序(a)和(b)的一些示例代码将非常有用


感谢您,只需将对象添加到计时器上的全局列表中,您就可以模拟内存泄漏。

只需创建IDisposable对象,而不要处置它们!示例包括
图像
图形
或任何类型的句柄或代码,这些句柄或代码分支为非托管代码以创建/管理资源。

泄漏的应用程序可能如下所示:

public static void Main()
{
  var list = new List<byte[]>();
  while (true)
  {
    list.Add(new byte[1024]); // Change the size here.
    Thread.Sleep(100); // Change the wait time here.
  }
}
public static void Main()
{
  Process process = Process.Start("leaker.exe");
  process.Kill();
}
看看这门课。有几种方法可以返回进程消耗的内存量。您可以使用其中一个来有条件地终止进程

以下内容解决了(a)控制台应用程序的渐进内存泄漏问题,您可以在其中设置泄漏量和泄漏持续时间

  • 逐渐消耗内存的控制台应用程序
  • 参数#1是它将消耗的内存(即6000是6千兆字节)
  • 参数#2是每次迭代的逐渐延迟(即1000是1秒)
  • 提交的内存和工作集大致相同
  • 它被设计为使用XmlNode作为占用内存的对象,因为这样,提交内存(操作系统中进程分配的内存)和工作集内存(进程实际使用的内存)将是相同的。如果使用一个primative类型来占用诸如byte[]数组之类的内存,那么工作集通常是空的,因为即使已经分配了内存,该内存实际上也不会被进程使用

    确保在“生成”选项卡下的“项目属性”下的x64中编译。否则,如果它是在x32中编译的,那么它将在1.7Gigs限制附近得到OutOfMemory错误。在x64中,它所消耗的内存将相当“无限”


    我用以下代码创建了我的:

    internal class Program
    {
        private static void Main(string[] args)
        {
            try
            {
                var limit = 9400;
                while (true)
                {
                    var thread = new Thread(() => IncreaseMemory(limit));
                    thread.Start();
                }
            }
            catch (Exception)
            {
                // swallow exception
            }
    
        }
    
        private static void IncreaseMemory(long limity)
        {
            var limit = limity;
    
            var list = new List<byte[]>();
            try
            {
                while(true)
                {
                    list.Add(new byte[limit]); // Change the size here.
                    Thread.Sleep(1000); // Change the wait time here.
                }
            }
    
            catch (Exception ex)
            {
                // do nothing
            }
        }
    
    }
    
    内部类程序
    {
    私有静态void Main(字符串[]args)
    {
    尝试
    {
    风险价值限额=9400;
    while(true)
    {
    var线程=新线程(()=>增加内存(限制));
    thread.Start();
    }
    }
    捕获(例外)
    {
    //吞咽异常
    }
    }
    专用静态无效增量内存(长限制)
    {
    var极限=极限;
    var list=新列表();
    尝试
    {
    while(true)
    {
    list.Add(新字节[limit]);//在此处更改大小。
    Thread.Sleep(1000);//更改此处的等待时间。
    }
    }
    捕获(例外情况除外)
    {
    //无所事事
    }
    }
    }
    
    我曾尝试使用公认答案中描述的方法,但没有成功-看起来编译器或运行时已经对此进行了优化

    我发现了最简单的修改,使这项工作:

    var rnd = new Random();
    var list = new List<byte[]>();
    while (true)
    {
        byte[] b = new byte[1024];
        b[rnd.Next(0, b.Length)] = byte.MaxValue;
        list.Add(b);
    
        Thread.Sleep(10);
    }
    
    var rnd=new Random();
    var list=新列表();
    while(true)
    {
    字节[]b=新字节[1024];
    b[rnd.Next(0,b.Length)]=byte.MaxValue;
    列表.添加(b);
    睡眠(10);
    }
    

    此代码使应用程序消耗越来越多的内存。

    在控制台或Win应用程序中创建一个
    面板
    对象(panel1),然后添加1000个
    图片框
    并设置其
    图像
    属性,然后调用
    面板1.控件。清除
    。所有PictureBox控件仍在内存中,无法通过
    GC
    收集它们:

    var panel1 = new Panel();
    var image = Image.FromFile("image/heavy.png");
    for(var i = 0; i < 1000;++i){
      panel1.Controls.Add(new PictureBox(){Image = image});
    }
    panel1.Controls.Clear(); // => Memory Leak!
    

    调用Clear方法不会从内存中删除控制句柄。 必须显式调用Dispose方法以避免内存泄漏


    这听起来像是家庭作业。IDisposable在这里没有什么特别的功能。任何对象都可以工作,只要你不让它变得不可访问。我实现了你的示例代码。My Leaker.exe以每个任务管理器进程选项卡6MB内存使用量开始。我不知道我可以用哪个属性来测量它。。。从NonpagedSystemMemorySize一直到VirtualMemorySize64,我在任何地方都可以得到几个属性,但我不知道哪个属性对应于任务管理器内存使用量。我试图将内存属性值打印到控制台,但仍然没有成功。请提供帮助。通过创建更大的
    字节
    数组,让泄漏者更积极地消耗内存。尝试使用
    privatemorysize64
    。随着时间的推移,它应该开始慢慢上升。这应该是正确的答案。现实世界,可能的错误。
    var rnd = new Random();
    var list = new List<byte[]>();
    while (true)
    {
        byte[] b = new byte[1024];
        b[rnd.Next(0, b.Length)] = byte.MaxValue;
        list.Add(b);
    
        Thread.Sleep(10);
    }
    
    var panel1 = new Panel();
    var image = Image.FromFile("image/heavy.png");
    for(var i = 0; i < 1000;++i){
      panel1.Controls.Add(new PictureBox(){Image = image});
    }
    panel1.Controls.Clear(); // => Memory Leak!
    
    for (int i = panel1.Controls.Count-1; i >= 0; --i)
       panel1.Controls[i].Dispose();