Ich habe festgestellt, dass meine Anwendung nicht genügend Arbeitsspeicher hat, als es sollte. Es erstellt viele Byte-Arrays von jeweils mehreren Megabyte. Wenn ich jedoch die Speicherauslastung mit vmmap untersuchte, scheint .NET viel mehr zuzuweisen, als für jeden Puffer erforderlich ist. Um genau zu sein, erstellt .NET bei der Zuweisung eines Puffers von 9 Megabyte einen Heap von 16 Megabyte. Die verbleibenden 7 Megabyte können nicht zum Erstellen eines weiteren Puffers von 9 Megabyte verwendet werden, daher erstellt .NET weitere 16 Megabyte. So verschwendet jeder 9MB Puffer 7MB Adressraum!Large Object Heap Verschwendung
Hier ist ein Beispielprogramm, das eine OutOfMemoryException nach Zuweisung 106 Puffer in 32-Bit-NET 4 wirft:
using System.Collections.Generic;
namespace CSharpMemoryAllocationTest
{
class Program
{
static void Main(string[] args)
{
var buffers = new List<byte[]>();
for (int i = 0; i < 130; ++i)
{
buffers.Add(new byte[9 * 1000 * 1024]);
}
}
}
}
Beachten Sie, dass die Größe des Arrays 16 erhöhen * 1000 * 1024 und noch zuzuteilen die gleiche Menge an Puffern vor dem Auslaufen des Arbeitsspeichers.
VMMap zeigt dies:
Beachten Sie auch, wie ein es gibt fast 100% Differenz zwischen der Gesamtzahl Größe des verwalteten Heap und die Gesamt Commited Größe. (1737MB vs 946MB).
Gibt es einen zuverlässigen Weg um dieses Problem auf .NET, d. H. Kann ich die Laufzeit in die Zuweisung von nicht mehr als das, was ich wirklich brauche, oder vielleicht viel größere Managed Heaps, die für mehrere zusammenhängende Puffer verwendet werden können?
Ihr Wunsch nach Speicherzuweisungen, die genau passen, was Sie brauchen, wird von einer viel größeren Sorge, die Notwendigkeit, Adressraumfragmentierung zu vermeiden, übertrumpft. Dieses Verhalten ist vollständig von Design, es gibt keine Knöpfe, um es zu optimieren. Altmodisches Problem sowieso, es ist kein Problem auf 64-Bit-Betriebssystemen. –
Kurze Antwort: Nein –
@HansPassant Leider muss dieser Prozess 32-Bit sein. Du sagst also im Grunde, dass ich meinen eigenen Allokator programmieren muss? – Asik