Esecuzione di un'applicazione .NET su Windows Server 2008 x64 con 16 GB di RAM. Questa applicazione deve recuperare e analizzare una grande quantità di dati (circa 64 GB) e conservarli tutti in memoria contemporaneamente.Garbage collector .NET e memoria virtuale x64
Cosa mi aspetto di vedere: le dimensioni del processo si espandono da 16 GB a 64 GB. Windows utilizza la memoria virtuale per inviare i dati aggiuntivi al/dal disco, se necessario. Questo è il classico caso d'uso della memoria virtuale.
Cosa vedo realmente: la dimensione del processo è limitata alla quantità di memoria fisica (16 GB). L'applicazione spende il 99,8% del suo tempo nel garbage collector.
Perché la nostra applicazione non riesce a utilizzare la memoria virtuale? Si tratta di un problema nella configurazione del garbage collector .NET o nel gestore della memoria virtuale x64 di Windows stesso? Cosa posso fare per far sì che la nostra applicazione utilizzi la memoria virtuale anziché essere limitata alla memoria fisica?
Grazie.
- Brian
Aggiornamento: Ho scritto un piccolo programma che presenta lo stesso comportamento:
using System;
namespace GCTest
{
class Program
{
static void Main()
{
byte[][] arrays = new byte[100000000][];
for (int i = 0; i < arrays.Length; ++i)
{
arrays[i] = new byte[320];
if (i % 100000 == 0)
{
Console.WriteLine("{0} arrays allocated", i);
System.Threading.Thread.Sleep(100);
}
}
}
}
}
Se volete provarlo, assicuratevi di costruire per x64. Potrebbe essere necessario modificare leggermente le costanti per sottolineare il sistema. Il comportamento che vedo è che il processo si blocca quando si avvicina a una dimensione di 16 GB. Non c'è nessun messaggio di errore o eccezione lanciata. Il monitor delle prestazioni segnala che la% del tempo della CPU in GC si avvicina al 100%.
Non è inaccettabile? Dov'è il sistema di memoria virtuale?
Che cosa state usando per determinare la dimensione del processo? (Eliminiamo prima le opzioni semplici :)) – Paolo
"Commit size" dal Task Manager di Windows. Utilizza anche "# byte impegnati totali" in Performance Monitor. Sono abbastanza sicuro che sto misurando le dimensioni della memoria virtuale del processo piuttosto che il suo set di lavoro fisico. – brianberns
Posso chiedere l'ovvio? Hai davvero bisogno di caricare tutto questo in memoria in una volta? È possibile prendere un altro approccio e fare una sorta di paging manuale da solo? – CodingGorilla