c# bytearray large-object-heap memory-fragmentation

c# - Fragmentación del montón cuando se utilizan matrices de bytes



bytearray large-object-heap (3)

¿Cuánto tiempo es tu byte [] array? ¿Caen en el objeto pequeño o en el montón de objetos grandes? Si experimentas una fragmentación de la memoria, diría que caen en la LOH.

Por lo tanto, debe reutilizar las mismas matrices de bytes (usar un grupo) o usar trozos más pequeños. La LOH nunca se compacta, por lo que puede fragmentarse bastante. Lamentablemente no hay manera de evitar esto. (Aparte de conocer esta limitación y evitarla)

Tengo una aplicación C # 4.0 (productor único / consumidor individual) que transfiere gran cantidad de datos en partes. Aunque no hay una nueva asignación de memoria, me quedo sin memoria después de un tiempo.

Perfilaba la memoria usando el perfilador de memoria de Redgate y hay mucha memoria libre allí. Dice que la memoria libre no se puede usar debido a la fragmentación.

Utilizo una colección de bloqueo como el búfer y las matrices de bytes como los miembros:

BlockingCollection<byte[]> segments = new BlockingCollection<byte[]>(8); // producer: segments.Add(buffer); // consumer: byte[] buffer = _segments.Take();

¿Cómo puedo evitar la fragmentación de la memoria gestionada?


El GC no compacta el montón de objetos grandes para usted, aún puede compactarlo programáticamente. El siguiente fragmento de código ilustra cómo se puede lograr esto.

GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; GC.Collect();


Probablemente se haya topado con el problema del montón de objetos grandes: los objetos de más de 85,000 bytes se colocan en el montón de objetos grandes que no se compactan, lo que puede llevar a situaciones extrañas de memoria. Aunque aparentemente el rendimiento en .NET 4 ha mejorado, está lejos de ser perfecto. La solución es básicamente usar su propio grupo de búferes que contiene algunos fragmentos de memoria asignados estáticamente y reutilizarlos.
Hay un montón de preguntas sobre eso en SO.

Actualización : Microsoft proporciona un administrador de búfer como parte de la pila WCF. También hay uno en codeproject .