System.Runtime.Caching.MemoryCache è una classe in .NET Framework (versione 4+) che memorizza nella memoria oggetti, utilizzando stringhe come chiavi. Più di System.Collections.Generic.Dictionary<string, object>, questa classe ha tutti i tipi di campane e fischietti che ti permettono di configurare a quanto può essere estesa la cache (in termini assoluti o relativi), impostare diverse politiche di scadenza per diversi elementi della cache e molto altro ancora.Cosa significano esattamente i limiti di memoria di MemoryCache?
Le mie domande riguardano i limiti di memoria. Nessuno dei documenti su MSDN sembra spiegare questo in modo soddisfacente, e il codice sulla fonte di riferimento è piuttosto opaco. Mi dispiace di aver accumulato tutto questo in una "domanda" SO, ma non riesco a capire come prenderne un po 'nelle loro domande, perché in realtà sono solo visioni diverse di una domanda generale: "come si concilia l'idioma C#? /.NET con la nozione di una cache in-memory generalmente utile che ha limiti di memoria configurabili implementati quasi interamente nel codice gestito? "
- Le dimensioni delle chiavi contano rispetto allo spazio occupato da MemoryCache? Per quanto riguarda le chiavi nel pool interno, ciascuna delle quali dovrebbe solo aggiungere la dimensione di un riferimento a un oggetto alla dimensione della cache?
- MemoryCache considera oltre le dimensioni dei riferimenti oggetto che memorizza quando determina la dimensione dell'oggetto che viene archiviato nel pool? Voglio dire ... deve, giusto? Altrimenti, le opzioni di configurazione sono estremamente fuorvianti per il caso comune ... per le restanti domande, assumerò che lo faccia.
- Dato che MemoryCache considera quasi certamente la dimensione dei riferimenti agli oggetti dei valori memorizzati nella cache, quanto è profondo?
- Se mi stavano attuando qualcosa di simile, mi troverei molto difficile da prendere in considerazione l'utilizzo della memoria dei componenti "figli" dei singoli oggetti, senza tirare anche nelle proprietà di riferimento "madre".
- ad esempio, immaginare una classe in un'applicazione di gioco,
Player
.Player
ha uno stato specifico per giocatore che è incapsulato in una proprietàpublic PlayerStateData PlayerState { get; }
che incapsula la direzione del giocatore, quanti pignoni reggono, ecc., Nonché un riferimento all'intero stato del giocopublic GameStateData GameState { get; }
che può essere utilizzato per ottenere ritorno allo stato (molto più grande) del gioco da un metodo che conosce solo un giocatore. - MemoryCache considera sia
PlayerState
siaGameState
quando si considera la dimensione del contributo alla cache? - Forse è più come "qual è la dimensione totale nell'heap gestito occupato dagli oggetti direttamente memorizzati nella cache e tutto ciò che è raggiungibile attraverso i membri di tali oggetti"?
- Sembra che sarebbe stupido moltiplicare le dimensioni del contributo di
GameState
al limite di 5 solo perché 5 giocatori sono memorizzati nella cache ... ma poi di nuovo, una probabile implementazione potrebbe fare proprio questo, ed è difficile contarePlayerState
senza contareGameState
.
- Se un oggetto viene memorizzato più volte nella MemoryCache, ciascuna voce viene conteggiata separatamente rispetto al limite?
- Relativo al precedente, se un oggetto è memorizzato direttamente nel MemoryCache, ma anche indirettamente attraverso i membri di un altro oggetto, quale impatto ha uno sul limite di memoria?
- Se un oggetto è memorizzato nel MemoryCache, ma viene anche referenziato da alcuni altri oggetti live completamente disconnessi dalla MemoryCache, quali oggetti contano rispetto al limite di memoria? Che dire se si tratta di una matrice di oggetti, alcuni (ma non tutti) di cui hanno riferimenti esterni in entrata?
La mia ricerca mi ha portato a SRef.cs, che ho rinunciato a cercare di capire dopo aver ottenuto here, che poi conduce here. Indovinare le risposte a tutte queste domande ruoterebbe attorno alla ricerca e alla meditazione sul codice che alla fine ha popolato l'INT64 che è memorizzato in quella maniglia.
IMO l'implementazione più utile della gestione dei limiti di MemoryCache implicherebbe che la cache sia in grado di rispondere perfettamente alla domanda, "se venissi cancellato e un GC completo fosse eseguito immediatamente dopo, quanti byte di memoria verrebbero liberati durante quella esecuzione di GC ?" Ma più penso a questo, più mi aspetto che la sua risposta sia pesantemente gonfiata se il proprietario della cache non rispetta un certo insieme di regole non rivelate (o almeno non scoperte), quindi questo è rilevante per più di un semplice ragioni teoriche –
Sono venuto qui chiedendo esattamente le stesse domande, in particolare per quanto riguarda i riferimenti allo stato condiviso. Un'altra domanda mi affligge anche ... supponendo che il tuo oggetto memorizzato nella cache (grafico) cresca o si ritiri dopo che è stato inserito nella cache ...? È tutto piuttosto vago. – spender