2009-06-01 1 views
26

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?Memoria massima che può essere allocata da un processo .NET

Alcuni esempi ciò che il metodo deve restituire:

1) Configurazione della Macchina: x 64 di Windows, 4GB di memoria fisica, file di paging 4 GB
-Come processo a 64 bit: 8 GB
-Come processo a 32 bit : 1.4GB

2) Configurazione della macchina: x 64 di Windows, 1 GB di memoria fisica, file di paging 2GB
-Come processo a 64 bit: 3GB
-Come processo a 32 bit: 1.4GB

3) Configurazione della Macchina: x32 Windows, 4GB di memoria fisica, file di paging 4 GB
-Come processo a 64 bit: Non accadrà
-Come processo a 32 bit: 1.4GB

4) Configurazione della Macchina: x32 con Windows, 512 MB di memoria fisica, file di pagina 512
-Come processo a 64 bit: non accadrà
-Come processo a 32 bit: 1.0GB

+0

Ecco un post interessante che parla di massimi teorici e intervalli in cui un processo .NET inizierà a vedere le eccezioni di memoria: http://blogs.msdn.com/b/ tom/archive/2008/04/10/chat-question-memory-limits-per-32-bit-and-64-bit-processes.aspx –

risposta

3

non dipende da quanta RAM avete ?

In teoria, un processo x64 è in grado di allocare gli EB (etabyte?) Di RAM, penso, cioè un LOTTO. Ma se lo fai, la tua macchina dovrebbe iniziare a impaginare come un matto e generalmente morire.

Era diverso nella modalità a 32 bit, in quanto non è stato possibile allocare più di 1 GB di RAM in QUALSIASI processo in Windows (sì, ci sono 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 è possibile utilizzare è 3 GB: il sistema operativo riserva 1 GB di spazio virtuale per sé.

In 64 bit, dovrebbe essere 2^64, che è un numero grande, ma http://en.wikipedia.org/wiki/X86-64 dice che è 256 TB di spazio virtuale e 1 TB di RAM REALE. 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 tempo di esecuzione a 64 bit, applicazioni .NET 2.0-based possono ora utilizzare 500 volte più memoria per i dati quali cache basate su server.

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

A proposito, se siete su una macchina x64 (vale a dire, la macchina x64 + OS x64), la compilazione per AnyCPU e x64 fa la stessa cosa - si corre in modalità x64. L'unica differenza è che se si utilizza AnyCPU VRS x86:

  • x64 OS/.NET, AnyCPU: 64 app
  • x64 OS /.NET, x64: 64 app
  • x64 OS/.NET, x32: x32 applicazione (.NET framework x64 in quanto entrambe le versioni x32 e x64 del Fx installati)

  • 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.
+0

Ma come posso ottenere il limite di memoria reale per una macchina? – Rauhotz

+0

Segnalo come male la tua risposta perché hai mescolato tutto. La memoria da 3 GB è la massima memoria fisica libera in cui si può vivere 1 o più processi. Qualsiasi processo può accedere all'intero spazio di 4 giga (indirizzo a 32 bit), la memoria che non può essere nella memoria fisica verrà memorizzata nella cache (se la cache è configurata correttamente). E nemmeno 3 concerti sono del tutto vere. Devi impostare XP, per impostazione predefinita sono solo 2 giga di RAM massimo per l'app e 2 concerti per l'os (della memoria fisica). –

+2

Scusa, Eric, ma devi leggerlo e provarlo. Il limite teorico su un sistema a 32 bit può essere 4 GB, ma Windows ti limita a 3 GB (l'altro GB è usato per il sistema, e devi usare/3GB nei parametri di avvio per ottenerlo), e mentre ogni processo ha un 4 GB di spazio, Windows o .NET FX impongono un limite di 1 GB per i processi che non fanno cose speciali (SQL e Exchange lo fanno). –

17

Windows può essere configurato per allocare più spazio per i file di pagina su richiesta o on request.
Job objects può impedire il consumo di più di una certa quantità di memoria.
frammentazione del cumulo e la natura generazionale di esso (più la necessità di mettere roba di grandi dimensioni nel Large Object Heap)

Tutto questo significa che il limite fisico non è molto utile, in realtà, e significa rispondere alla domanda "come molta memoria che potrei allocare teoricamente "è piuttosto più complessa di quanto pensi.

Dal momento che è complesso chiunque chiedendo questa domanda è probabilmente cercando di fare qualcosa di sbagliato e deve riorientare la loro domanda per qualcosa di più utile.

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

"Voglio solo sapere quando il carico di memoria attuale del processo potrebbe ottenere problematico così posso prendere azioni come liberare alcuni elementi di una cache personalizzata."

Diritto. questa è una domanda molto più trattabile.

Due soluzioni in ordine di complessità:

  1. Fai la tua cache utilizzano WeakReferences
    • Ciò significa che le cose saranno liberati dal sistema quasi magicamente per voi, ma si avrà poco controllo su cose come la politica di sostituzione
    • si basa sui dati memorizzati nella cache molto più grande della chiave e sul sovraccarico di un riferimento debole
  2. Registrati notification of Garbage Collections
    • Questo ti permette di prendere il controllo di liberare le cose.
    • ci si basa sul sistema che ha 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 dal suono di esso) piuttosto che ricalcolare/ri-richiedere i dati.
Se la cache mostra una scarsa localizzazione tra articoli richiesti in modo comune/consecutivo, 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)

Come parte a parte: In. Net, nessun oggetto 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. (ed entrambe le soluzioni sopra trarranno vantaggio da questo)

+0

Voglio solo sapere quando il carico di memoria corrente del processo potrebbe diventare problematico, così posso intraprendere azioni come liberare alcuni elementi di una cache personalizzata. Il valore non deve essere accurato al 100%, solo un suggerimento per la mia cache. Attualmente ho la quantità di memoria fisica libera come limite, ma per i processi a 32 bit la barriera è più bassa. – Rauhotz

+0

BTW: buon punto con la dimensione del file di pagina dinamica, è mancato, ma per ora, sarei soddisfatto del limite attuale. – Rauhotz

+0

Aha - ora stiamo arrivando da qualche parte - modifica delle risposte ora – ShuggyCoUk