2010-06-10 21 views
6

Me gustaría escribir el siguiente código en C#. a) pequeña aplicación de consola que simula la pérdida de memoria. b) pequeña aplicación de consola que invoca la aplicación anterior y la libera de inmediato simulando el problema de gestión de fuga de memoria ...C#: simular pérdidas de memoria

En otras palabras, la aplicación (b) llamaría continuamente y lanzaría la aplicación (a) para simular cómo rebelde "la aplicación de pérdida de memoria se está conteniendo sin abordar la causa raíz que es la aplicación (a).

Algunos ejemplos de código para la aplicación (a) y (b) serían muy útiles.

Gracias

+2

Esto me suena a tarea. –

Respuesta

11

La aplicación fuga podría ser:

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

Y la aplicación de llamada podría ser:

public static void Main() 
{ 
    Process process = Process.Start("leaker.exe"); 
    process.Kill(); 
} 

Tome un vistazo a la clase properties on the Process. Hay varios que devuelven la cantidad de memoria que consume el proceso. Puede usar uno de ellos para matar condicionalmente el proceso.

+0

Implementé su código de muestra. My Leaker.exe comienza con un uso de memoria de 6MB por pestaña de proceso del administrador de tareas. No sé qué propiedad podría usar para medirla ... Obtuve varias propiedades en cualquier lugar, desde NonpagedSystemMemorySize hasta VirtualMemorySize64, pero no sé qué propiedad correspondería al uso de memoria de Task Manager. Traté de imprimir valores de propiedades de memoria a la consola, pero todavía no tuve suerte. Por favor ayuda. –

+0

Haga que el extractor consuma memoria de manera más agresiva creando una matriz de 'byte 'más grande. Intenta usar 'PrivateMemorySize64'. Debería comenzar a arrastrarse con el tiempo. –

1

puede simular una pérdida de memoria, simplemente añadiendo objetos a una lista global en un temporizador.

3

¡Solo crea objetos identificables y no los deseches! Los ejemplos son ImageGraphics o cualquier tipo de identificador o código que se bifurca en código no administrado para crear/administrar recursos.

+1

IDisposable no hace nada especial aquí. Cualquier objeto funcionará, siempre y cuando no lo deje inalcanzable. – Joey

0

A continuación, se trata de lo que desea en (a) una fuga de memoria gradual de una aplicación de consola donde puede establecer la cantidad de fuga y la duración para filtrarla.

  1. aplicación de consola que se come poco a poco la memoria
  2. parámetro # 1 es la memoria que se comen en Megabytes (es decir 6000 es de 6 conciertos)
  3. parámetro # 2 es el retardo gradual para cada iteración (es decir, 1.000 es de 1 segundo)
  4. la memoria asignada y conjunto de trabajo será de alrededor del mismo

fue diseñado para use XmlNode como el objeto que ocupa la Memoria porque entonces la MEMORIA COMPROMETIDA (memoria asignada por proceso en OS) y la MEMORIA DE CONFIGURACIÓN DE TRABAJO (memoria realmente utilizada por el proceso) serían las mismas. Si se utiliza un tipo de primative para tomar memoria, como una matriz byte [], entonces el CONJUNTO DE TRABAJO generalmente no es nada, ya que el proceso no utiliza realmente la memoria aunque esté asignada.

Asegúrese de compilar en x64 en Propiedades del proyecto en la pestaña Compilar. De lo contrario, si está compilado en x32, recibirá un error OutOfMemory alrededor del límite de 1.7Gigs. En x64, la memoria que se come será bastante "ilimitada".

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

     } 

    } 
} 

Y como respuesta de Brian Gedeón ya se recomienda, puede llamar a esto usando el siguiente código y luego matar el proceso de su parte (b).El ejemplo siguiente llama a MemoryHog.exe (el programa desde el código anterior) a comer hasta 6 conciertos y haciendo una pausa cada 2 segundos

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

creé el mío con este código:

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

tengo intenté utilizar el enfoque, descrito en la respuesta aceptada, pero no funcionó; parece que el compilador o el tiempo de ejecución lo han optimizado.

he encontrado la modificación más simple que hace que este trabajo:

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

Este código hace que la aplicación consume más y más memoria.

Cuestiones relacionadas