2010-06-10 2 views
6

Я хотел бы написать следующий код в C#. a) небольшое консольное приложение, которое имитирует утечку памяти. b) маленькое консольное приложение, которое будет ссылаться на вышеуказанное приложение и сразу же выпустить его, имитируя проблему с утечкой памяти.C#: имитировать утечки памяти

Другими словами, приложение (b) будет непрерывно вызывать и освобождать приложение (а) для имитации того, как " бунтарское "приложение утечки памяти, содержащееся с устранением основной причины, которая является приложением (а).

Некоторые примеры кода приложения (a) и (b) были бы очень полезными.

Благодаря

+2

Это звучит как домашнее задание для меня. –

ответ

11

Приложение протечки может выглядеть следующим образом:

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 класса. Есть несколько, которые возвращают объем памяти, потребляемой процессом. Вы можете использовать один из них, чтобы условно убить процесс.

+0

Я реализовал ваш пример кода. My Leaker.exe начинается с использования памяти 6MB на вкладке процесса менеджера задач. Я не знаю, какое свойство я мог бы использовать для его измерения ... Я получаю несколько свойств в любом месте от NonpagedSystemMemorySize до VirtualMemorySize64, но я не знаю, какое свойство будет соответствовать использованию памяти диспетчера задач. Я попытался напечатать значения свойств памяти для консоли, но все равно не повезло. Пожалуйста помоги. –

+0

Имейте более интенсивно потребляющую память, создавая большой массив 'byte'. Попробуйте использовать 'PrivateMemorySize64'. С течением времени он должен начинать ползать. –

1

Вы можете имитировать утечку памяти путем простого добавления объектов в глобальный список по таймеру.

3

Просто создайте объекты IDisposable и не уничтожайте их! Примерами являются ImageGraphics или любой вид дескриптора или кода, который выходит из неуправляемого кода для создания/управления ресурсами.

+1

IDisposable не делает ничего особенного здесь. Любой объект будет работать, если вы не позволите ему стать недоступным. – Joey

0

Ниже перечислены то, что вы хотите в (a) постепенном утечке памяти из приложения консоли, где вы можете установить количество утечки и продолжительность его утечки.

    App
  1. консоли, которая постепенно съедает память
  2. Параметр # 1 является памятью он будет съедать в мегабайтах (т.е. 6000 является 6 Кабриолетов)
  3. Параметр # 2 является постепенной задержки для каждой итерации (т.е. 1000 является 1 секунда)
  4. допущенное памяти и Working Set будет примерно в то же

Он был разработан для используйте XmlNode как объект, который занимает память, потому что тогда COMMITTED MEMORY (память, выделенная процессом в ОС) и WORKING SET MEMORY (память, фактически используемая процессом) будет одинаковой. Если примитивный тип используется для захвата памяти, такой как массив byte [], тогда WORKING SET обычно ничего, потому что память фактически не используется процессом, даже если она была выделена.

Обязательно выполните компиляцию в x64 в разделе Свойства проекта на вкладке «Сборка». В противном случае, если он скомпилирован в x32, тогда он получит ошибку OutOfMemory вокруг предела 1.7Gigs. В 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(); 

     } 

    } 
} 

И как ответ Брайан Гидеона уже рекомендовал, вы можете назвать это, используя следующий код, а затем убить процесс вашей части (б).В приведенном ниже примере вызывает 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(); 

     } 
    } 
} 
0

Я создал мину с этим кодом:

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 
     } 
    } 

} 
0

У меня есть попытался использовать подход, описанный в принятом ответе, но он не сработал - похоже, что компилятор или среда выполнения оптимизировали это.

Я нашел самую простую модификацию, которая делает эту работу:

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); 
} 

Этот код делает приложение потреблять все больше и больше памяти.

Смежные вопросы