Esiste un limite di memoria per un singolo processo .NET

Attualmente stiamo pensando di build un sistema di cache per contenere i dati estratti da un database SQL e renderli disponibili per un paio di altre applicazioni (sito Web, servizio web, ecc.). Immaginiamo che la cache sia in esecuzione come servizio Windows e consiste essenzialmente in un dizionario intelligente che contiene le voci della cache. La mia domanda è, c’è un limite al working set dell’applicazione (sarà eseguito su Windows Server 2003)? O la quantità di memoria fisica è il limite?

32 bit o 64 bit? 32 bit è 2 GB (per un processo), 64 bit è 1 TB (server Enterprise Edition 2003) .

Tuttavia, la dimensione massima di un object CLR è di 2 GB anche su 64 bit.

Aggiornamento: le informazioni sopra riportate erano corrette nel 2008. Vedi la risposta di Ohad per informazioni più recenti. Il server Windows 2016 può avere un massimo di 24 TB .

Recentemente ho eseguito una profilazione approfondita sui limiti di memoria in .NET su un processo a 32 bit. Siamo tutti bombardati dall’idea che possiamo allocare fino a 2,4 GB (2 ^ 31) in un’applicazione .NET ma sfortunatamente questo non è vero :(. Il processo di applicazione ha così tanto spazio da usare e il sistema operativo fa un grande Tuttavia, lo stesso .NET sembra avere il proprio overhead che rappresenta circa 600-800 MB per le tipiche applicazioni del mondo reale che spingono il limite di memoria. Ciò significa che non appena si assegna un array di numeri interi che richiede circa 1,4 GB, dovresti aspettarti di vedere un OutOfMemoryException ().

Ovviamente a 64 bit, questo limite si verifica in un secondo momento (parliamo tra 5 anni :)), ma cresce anche la dimensione generale di tutto ciò che è in memoria (trovo che va da ~ 1.7 a ~ 2 volte) a causa dell’aumento delle dimensioni delle parole.

Quello che so per certo è che l’idea di memoria virtuale dal sistema operativo NON ti dà praticamente spazio di allocazione praticamente infinito all’interno di un unico processo. È solo lì in modo che l’intero 2,4 GB è indirizzabile a tutte le (molte) applicazioni in esecuzione contemporaneamente.

La seguente tabella di MSDN è la risposta più precisa alla tua query. Si noti che il flag IMAGE_FILE_LARGE_ADDRESS_AWARE non può essere impostato direttamente dal compilatore gestito, anche se per fortuna può essere impostato post build tramite l’utilità editbin . 4GT si riferisce al flag / 3gb.

alt text

Su Windows a 32 bit puoi ottenere un po ‘di memoria in più avviando Windows con il flag / 3gb e contrassegnando la tua app come “grande indirizzamento”

Mattia,

Non è in realtà una risposta alla domanda diretta, ma un altro modo di affrontare questo problema che aggirerà alcune delle grandi insidie, che possono essere un grosso problema con le soluzioni di memorizzazione nella cache. (Scusate, non ho alcuna lettura raccomandata sull’argomento).

Lo abbiamo implementato in un progetto precedente e ha creato altri problemi.

Per l’accesso offline, puoi usare sql express sui desktop per creare un mirror del tuo database (o solo il bit che devi memorizzare nella cache)? Quindi tutto ciò che devi fare è cambiare il database a cui punta l’applicazione. Puoi persino usarlo per memorizzare le diff e riprodurle sul server, anche se questo ha altri problemi. È ansible modificare le autorizzazioni sulla copia locale per renderlo di sola lettura se è così che dovrebbe essere.

I dizionari che stai pensando di creare suonano notevolmente come gli indici Sql. Mi affiderei a sql per fare il lavoro per te, se puoi architettarlo in quel modo. Perché reinventare quella ruota? Se lo fai, dovrai pensare attentamente alla scadenza della cache e alla gestione della memoria, in particolare se si tratta di un servizio Windows.

In bocca al lupo,

Sam

Come con qualsiasi altro programma Windows, sei limitato dallo spazio degli indirizzi. Cioè: su 32 bit, puoi avere 2GB di spazio di indirizzamento. Su x64, puoi avere 8 TB.

Se non hai 8 TB di memoria fisica, inizierà la pagina.