2010-05-06 16 views
18

Necesito refactorizar mi proyecto para hacerlo inmune a la excepción OutOfMemory.Cómo simular excepción OutOfMemory

Hay enormes colecciones utilizadas en mi proyecto y cambiando un parámetro que puedo hacer que mi programa sea más precisa o utilizar menos de la memoria ...

OK, eso es el fondo. Lo que me gustaría hacer es ejecutar las rutinas en un bucle:

  1. Ejecute las subrutinas con el parámetro predeterminado.
  2. Capture la excepción OutOfMemory, cambie el parámetro e intente ejecutarlo nuevamente.
  3. Haga el 2do punto hasta que los parámetros permitan ejecutar las subrutinas sin lanzar la excepción (por lo general, solo se necesitará un cambio).

Ahora, me gustaría probarlo. Sé que puedo lanzar la excepción OutOfMemory por mi cuenta, pero me gustaría simular alguna situación real.

Así que la pregunta principal es:
¿Hay una manera de establecer algún tipo de límite de memoria para mi programa, después de llegar a la que el OutOfMemory excepción será lanzado de forma automática?
Por ejemplo, me gustaría establecer un límite, digamos 400MB de memoria para todo mi programa para simular la situación cuando hay una cantidad de memoria disponible en el sistema.
¿Se puede hacer?

Respuesta

2

me gustaría sugerir otra manera de mirar esto. No necesariamente debe quedarse sin memoria. Solo necesita controlar la cantidad de memoria utilizada y compararla con la memoria total del sistema. Tal vez algo como GC.GetTotalMemory será útil aquí para ver cuánta memoria está usando su aplicación. Luego, perhaps this article ayudará a obtener la cantidad total de RAM física disponible en su sistema.

+0

Bueno, incluso no necesito compararlo con la memoria del sistema, solo necesito saber cuánto MB de RAM usé mi programa. Necesito leer el doc para GC ... ¡gracias! – Gacek

+0

ok ... bueno, ya que estabas buscando OutOfMemoryException, asumí que querías quedarte sin un punto para afinar el máximo rendimiento. Pero bueno, si los métodos de GC funcionan para ti, ¡genial! – Dave

+0

Bueno, supongo que puedo usar los métodos de GC y arrojar la excepción por mi cuenta después de llegar a algún límite. Tal vez algún trabajador de fondo ... Necesito probar si funcionaría. – Gacek

5

Simplemente asigne una matriz muy grande. Lo más probable es que empiece a quedar fuera de las excepciones de memoria una vez que su aplicación C# alcance 1,2-1,6 GB de uso de RAM (generalmente en el lado inferior de ese rango, siempre que esté dirigido a x86).

+0

Bien, pero es lo mismo que puedo obtener lanzando la excepción OutOfMemory por mi cuenta. Quiero simular una situación real y probarla usando algunos conjuntos de datos pequeños (que consumen alrededor de 400 MB de memoria RAM en lugar de 1.6 GB) – Gacek

+0

Eso no funcionará de manera confiable en 64 bits. – Thorsten79

+0

Mejor, comience a construir un conjunto de matrices con 1 GB de longitud cada una. Podrás reproducirlo bastante rápido. – Nayan

6
public void EatMemory() 
{ 
    List<byte[]> wastedMemory = new List<byte[]>(); 

    while(true) 
    { 
     byte[] buffer = new byte[4096]; // Allocate 4kb 
     wastedMemory.Add(buffer); 
    } 
} 

no debe tomar mucho tiempo a menos que tengas 12 GB de RAM :)

+3

Om nom nom! Windows limita las aplicaciones a 2 GB de memoria en x86 y creo que es un poco más alta en 64 bits, por lo que 12 GB no importarán. – NibblyPig

+0

Interesante, ejecuté el código anterior y acertó mi PC. Windows dejó de responder por completo, y finalmente llegué al administrador de tareas para ver Visual Studio usando 3GB de memoria. No obtuve ninguna excepción, y el uso de la memoria siguió subiendo a unos 3,1 GB y luego volviendo a 3 GB ... Tengo 4 GB de ram. – NibblyPig

+0

@SLC: el archivo de página probablemente te protegió contra eso, lo que probablemente haya surgido cuando notaste que tu PC se ralentizaba. – Dave

16

Esto parece un trabajo para ... System.Runtime.MemoryFailPoint.

http://msdn.microsoft.com/en-us/library/system.runtime.memoryfailpoint.aspx

creo que el ejemplo en el enlace se adapte a su situación. Establezca el MemoryFailPoint en el nivel que necesite y luego tome la InsufficientMemoryException y ajuste los parámetros de entrada según corresponda.

+0

Parece que esta clase funciona bastante diferente de lo que necesito. En realidad comprueba si hay disponible cierta cantidad de memoria (por ejemplo, llamando a 'MemoryFailPoint (100)' uno puede verificar si la operación que consume 100MB se puede ejecutar. Lo que necesito es verificar cuánta memoria mi programa ya consumió. – Gacek

2

Una buena forma de simular una excepción de falta de memoria es ejecutar el programa en una máquina virtual (VM). Puede establecer la asignación máxima de memoria para la máquina virtual a un nivel lo suficientemente pequeño como para crear presión de memoria en su programa y provocar la excepción.

Algunas máquinas virtuales de código abierto son: QEMU, xen y kvm. Una buena máquina virtual comercial es VMware Fusion para Mac OS X o VMware Player para Linux/Windows.

2
string value = new string('crazy', int.MaxValue); 
Cuestiones relacionadas