Memoria massima che può essere allocata da un processo .NET

Qual è la memoria massima che il garbage collector può allocare per un processo .NET? Quando compilo a x64, Process.GetCurrentProcess.MaxWorkingSet restituisce circa 1,4 GB, ma quando compilo a AnyCPU (x64) viene restituito lo stesso numero. Per x64 dovrebbe essere più simile al valore “Limite” che viene visualizzato nel Task Manager. Come posso ottenere il numero corretto che causerà OutOfMemory-Exceptions quando viene superato in tutti i casi?

Alcuni esempi su cosa dovrebbe restituire il metodo:

1) Configurazione della macchina: x64-Windows, memoria fisica da 4 GB, file di 4 GB
-Come processo a 64 bit: 8 GB
-Come processo a 32 bit: 1,4 GB

2) Configurazione della macchina: x64-Windows, memoria fisica da 1 GB, file di pagine da 2 GB
-Come processo a 64 bit: 3 GB
-Come processo a 32 bit: 1,4 GB

3) Configurazione della macchina: x32-Windows, memoria fisica da 4 GB, file di pagine da 4 GB
-Come processo a 64 bit: non accadrà
-Come processo a 32 bit: 1,4 GB

4) Configurazione della macchina: x32-Windows, 512 MB di memoria fisica, 512 MB di file di paging
-Come processo a 64 bit: non accadrà
– Come processo a 32 bit: 1,0 GB

Windows può essere configurato per allocare più spazio per i file di pagina su richiesta o su richiesta .
Gli oggetti lavoro possono impedire il consumo di più di una certa quantità di memoria.
Frammentazione dell’heap e natura generazionale di esso (oltre alla necessità di inserire elementi di grandi dimensioni nell’Heap di oggetti di grandi dimensioni)

Tutto ciò significa che il limite difficile non è molto utile in realtà e significa rispondere alla domanda “quanto memoria posso allocare teoricamente” è piuttosto più complessa di quanto si pensi.

Dal momento che è complesso, chiunque faccia questa domanda probabilmente sta cercando di fare qualcosa di sbagliato e dovrebbe redirect la sua domanda a qualcosa di più utile.

Che cosa stai cercando di fare sembra richiedere una simile domanda?

“Voglio solo sapere quando l’attuale carico di memoria del processo potrebbe diventare problematico, così posso intraprendere azioni come liberare alcuni elementi di una cache personalizzata.”

Destra. questa è una domanda molto più trattabile.

Due soluzioni in ordine di complessità:

  1. Fai in modo che le tue cache utilizzino le DeboleRiferimenti
    • Ciò significa che le cose verranno liberate dal sistema quasi magicamente per te, ma avrai poco controllo su cose come la politica di sostituzione
    • ciò si basa sul fatto che i dati nella cache sono molto più grandi della chiave e il sovraccarico di un riferimento debole
  2. Registrati per la notifica di Garbage Collections
    • Questo ti permette di prendere il controllo di liberare le cose.
    • ci si basa sul sistema con la dimensione massima appropriata per le generazioni di GC, che potrebbe richiedere del tempo per raggiungere uno stato stazionario.

Punti da notare. È davvero meno costoso mantenere questa enorme cache (andando sul disco con i suoni di esso) piuttosto che ricalcolare / ri-richiedere i dati.
Se la tua cache mostra una scarsa localizzazione tra gli elementi richiesti comunemente / consecutivamente, molto impegno verrà speso per i dati di paging. Una cache più piccola con una politica di relassamento sintonizzata efficace ha buone probabilità di ottenere risultati notevolmente migliori (e con un impatto molto minore su altri programmi in esecuzione)

Per inciso: in. Net, nessun object di dimensioni variabili (stringhe, matrici) può avere una dimensione superiore a 2 GB a causa delle limitazioni delle strutture CLR core per la gestione della memoria. (e entrambe le soluzioni sopra trarranno beneficio da questo)

Non dipende da quanta RAM hai?

In teoria, un processo x64 può allocare EB (etabyte?) Di RAM, penso – cioè, molto. Ma se lo fai, la tua macchina dovrebbe iniziare a impaginare come un matto e generalmente morire.

Era diverso nella modalità a 32 bit, dato che non si poteva allocare più di 1 GB di RAM in QUALSIASI processo di Windows (sì, ci sono dei modi per aggirarlo, ma non è bello). In pratica, questo è circa 7-800meg per processo .NET, poiché .NET ha riservato un po ‘di spazio.

In entrambi i casi, a 32 bit, il massimo che puoi utilizzare è 3 GB: il sistema operativo riserva 1 GB di spazio virtuale per se stesso.

A 64 bit, dovrebbe essere 2 ^ 64, che è un grande numero, ma http://en.wikipedia.org/wiki/X86-64 dice che sono 256 TB di spazio virtuale e 1 TB di REAL RAM. In ogni caso, è molto più di quanto è probabile che tu abbia nella tua macchina, quindi andrà a colpire il file di paging.

Con un sistema operativo a 64 bit e un runtime a 64 bit, le applicazioni basate su .NET 2.0 ora possono utilizzare una memoria 500 volte superiore per dati come le cache basate su server.

Questo ha alcune buone informazioni, anche http://www.theserverside.net/tt/articles/showarticle.tss?id=NET2BMNov64Bit

BTW, se sei su una macchina x64 (cioè, x64 machine + x64 OS), la compilazione per AnyCPU e x64 fa la stessa cosa: funziona in modalità x64. L’unica differenza è se usi AnyCPU vrs x86:

  • x64 OS / .NET, AnyCpu: app x64
  • x64 OS / .NET, x64: x64 app
  • x64 OS / .NET, x32: x32 app (x64 .NET framework come ENTRAMBI le versioni x32 e x64 di Fx installate)

  • x32 OS / NET, AnyCPU: x32 app

  • x32 OS / .NET, x64: CRASH E BURN BABY! (in realtà, muore con grazia)
  • x32 OS / .NET, x32: x32 app.