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