我想在c#中編寫下面的代碼。 a)模擬內存泄漏的小型控制檯應用程序。 (b)應用程序將不斷地調用和釋放應用程序(a)來模擬如何將「應用程序」(a)模擬爲「叛逆「的內存泄露應用程序正被包含在內,以解決應用程序(a)的根本原因。c#:模擬內存泄漏
應用程序(a)和(b)的一些示例代碼將非常有幫助。
感謝
我想在c#中編寫下面的代碼。 a)模擬內存泄漏的小型控制檯應用程序。 (b)應用程序將不斷地調用和釋放應用程序(a)來模擬如何將「應用程序」(a)模擬爲「叛逆「的內存泄露應用程序正被包含在內,以解決應用程序(a)的根本原因。c#:模擬內存泄漏
應用程序(a)和(b)的一些示例代碼將非常有幫助。
感謝
泄漏的應用程序可能看起來像:
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();
}
看看在properties on the Process類。有幾個返回進程正在消耗多少內存。您可能能夠使用其中之一來有條件地終止進程。
我實現了你的示例代碼。我的Leaker.exe從每個任務管理器進程選項卡啓動6MB內存使用。我不知道我可以使用哪個屬性來衡量它......我從NonpagedSystemMemorySize一直到VirtualMemorySize64的任何位置都獲得了幾個屬性,但我不知道哪個屬性對應於任務管理器的內存使用情況。我試圖打印內存屬性值來控制,但仍然沒有運氣。請幫忙。 – 2010-06-11 22:55:48
通過創建一個更大的'byte'數組,可以讓leaker更積極地消耗內存。嘗試使用'PrivateMemorySize64'。它應該會隨着時間的推移而逐漸上升。 – 2010-06-12 01:49:37
您可以通過簡單地將對象添加到全局列表中的計時器模擬內存泄漏。
只需創建IDisposable對象並且不要處理它們!示例是Image
Graphics
或分支到非託管代碼以創建/管理資源的任何類型的句柄或代碼。
IDisposable在這裏沒有做任何特別的事情。任何物體都可以工作,只要你不讓它變得無法到達。 – Joey 2010-06-10 23:41:41
以下內容解決了(a)控制檯應用程序中的漸進式內存泄漏,您可以在其中設置泄漏量和泄漏持續時間。
它被設計爲使用XmlNode作爲佔用內存的對象,因爲那麼COMMITTED MEMORY(由OS中的進程分配的內存)和WORKING SET MEMORY(進程實際使用的內存)將是相同的。如果使用主數據類型來佔用內存,如byte []數組,那麼WORKING SET通常不算什麼,因爲儘管分配了內存,但內存實際上並未被進程使用。
確保在x64下的Build選項下的Project Properties下編譯。否則,如果它在x32中編譯,那麼它將在1.7Gigs限制附近得到一個OutOfMemory錯誤。在x64中,它消耗的內存將非常「無限」。
using System;
using System.Xml;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace MemoryHog
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(" Total Memory To Eat Up in Megs: " + args[0]);
Console.WriteLine("Millisecs Pause Between Increments: " + args[1]);
int memoryTotalInMegaBytes = Convert.ToInt32(args[0]);
int secondsToPause = Convert.ToInt32(args[1]);
Console.WriteLine("Memory Usage:" + Convert.ToString(GC.GetTotalMemory(false)));
long runningTotal = GC.GetTotalMemory(false);
long endingMemoryLimit = Convert.ToInt64(memoryTotalInMegaBytes) * 1000 * 1000;
List<XmlNode> memList = new List<XmlNode>();
while (runningTotal <= endingMemoryLimit)
{
XmlDocument doc = new XmlDocument();
for (int i=0; i < 1000000; i++)
{
XmlNode x = doc.CreateNode(XmlNodeType.Element, "hello", "");
memList.Add(x);
}
runningTotal = GC.GetTotalMemory(false);
Console.WriteLine("Memory Usage:" + Convert.ToString(GC.GetTotalMemory(false)));
Thread.Sleep(secondsToPause);
}
Console.ReadLine();
}
}
}
正如布萊恩基甸的答案已經建議,您可以通過使用下面的代碼,然後殺死進程的一部分調用這個(B)。下面的示例調用MemoryHog.exe(從上面的代碼中的程序),吃起來6場演出和暫停每2秒
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;
namespace ProcessLauncher
{
class Program
{
static void Main(string[] args)
{
Process process = Process.Start("MemoryHog.exe", "6000 2000");
Console.Read();
process.Kill();
}
}
}
我創建礦與此代碼:
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
}
}
}
我有試圖使用接受的答案中描述的方法,但它不起作用 - 它看起來像編譯器或運行時已經優化了這一點。
我發現這使得這項工作的最簡單的修改:
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);
}
這段代碼的應用程序消耗越來越多的內存。
這聽起來像是我的功課。 – 2010-06-10 23:26:35