Differenza tra "on-heap" e "off-heap"


Risposte:


169

Il negozio on-heap si riferisce agli oggetti che saranno presenti nell'heap Java (e anche soggetti a GC). D'altra parte, l'archivio off-heap si riferisce a oggetti (serializzati) gestiti da EHCache, ma memorizzati all'esterno dell'heap (e anche non soggetti a GC). Poiché l'archivio off-heap continua a essere gestito in memoria, è leggermente più lento dell'archivio on-heap, ma comunque più veloce dell'archivio su disco.

I dettagli interni coinvolti nella gestione e nell'utilizzo del negozio off-heap non sono molto evidenti nel link pubblicato nella domanda, quindi sarebbe saggio controllare i dettagli di Terracotta BigMemory , che viene utilizzato per gestire il disco fisso negozio. BigMemory (il negozio off-heap) deve essere utilizzato per evitare il sovraccarico di GC su un heap di diversi Megabyte o Gigabyte. BigMemory utilizza lo spazio degli indirizzi di memoria del processo JVM, tramite ByteBuffer diretti che non sono soggetti a GC a differenza di altri oggetti Java nativi.


18
+1 per menzionare i ByteBuffer diretti per ulteriori esplorazioni;)
Max

3
I ByteBuffer diretti offrono accesso alla memoria non gestita, ma sono essi stessi soggetti a GC (al contrario dei dati a cui fanno riferimento). Questo è importante perché un GC ByteBuffer diretto (il tipo ByteBuffer.allocateDirect, non il tipo MMap) verrà raccolto dal GC e quando viene raccolto viene attivato il Deallocater, raccogliendo efficacemente anche la memoria non gestita.
Nitsan Wakart,

L'uso di Unsafe per allocare oggetti sembra avere prestazioni di lettura e scrittura significativamente migliori su Onheap / DirectByteBuffers / ByteBuffers. ashkrit.blogspot.com/2013/07/…
Joe C

98

da http://code.google.com/p/fast-serialization/wiki/QuickStartHeapOff

Che cos'è l'heap-offloading?

Di solito tutti gli oggetti non temporanei assegnati vengono gestiti dal garbage collector di java. Sebbene la VM faccia un lavoro decente eseguendo la garbage collection, a un certo punto la VM deve fare un cosiddetto "GC completo". Un GC completo implica la scansione dell'heap allocato completo, il che significa che le pause / i rallentamenti del GC sono proporzionali alla dimensione dell'heap di un'applicazione. Quindi non fidarti di nessuno che ti dice "La memoria è economica". Nella memoria java il consumo fa male alle prestazioni. Inoltre, è possibile ottenere pause notevoli utilizzando dimensioni heap> 1 GB. Questo può essere sgradevole se hai cose quasi in tempo reale in corso, in un cluster o in una griglia un processo Java potrebbe non rispondere e cadere dal cluster.

Tuttavia, le applicazioni server odierne (spesso costruite su framework bloaty ;-)) richiedono facilmente cumuli ben oltre i 4Gb.

Una soluzione a questi requisiti di memoria è quella di "scaricare" parti degli oggetti nell'heap non java (allocato direttamente dal sistema operativo). Fortunatamente java.nio fornisce classi per allocare / leggere e scrivere direttamente blocchi di memoria "non gestiti" (anche file mappati in memoria).

Quindi è possibile allocare grandi quantità di memoria "non gestita" e utilizzarla per salvare oggetti lì. Per salvare oggetti arbitrari nella memoria non gestita, la soluzione più praticabile è l'uso della serializzazione. Ciò significa che l'applicazione serializza gli oggetti nella memoria offheap, in seguito l'oggetto può essere letto usando la deserializzazione.

Le dimensioni dell'heap gestite dalla java VM possono essere ridotte, quindi le pause GC sono in millesimi, tutti sono felici, lavoro fatto.

È chiaro che le prestazioni di tale buffer off heap dipendono principalmente dalle prestazioni dell'implementazione della serializzazione. Buone notizie: per qualche motivo la serializzazione FST è piuttosto veloce :-).

Esempi di utilizzo:

  • Cache di sessione in un'applicazione server. Utilizzare un file mappato in memoria per archiviare gigabyte di sessioni utente (inattive). Una volta che l'utente accede all'applicazione, è possibile accedere rapidamente ai dati relativi all'utente senza dover gestire un database.
  • Memorizzazione nella cache dei risultati computazionali (query, pagine html, ..) (applicabile solo se il calcolo è più lento della deserializzazione dell'oggetto risultato ofc).
  • persistenza molto semplice e veloce utilizzando file mappati in memoria

Modifica: per alcuni scenari si potrebbero scegliere algoritmi di Garbage Collection più sofisticati come ConcurrentMarkAndSweep o G1 per supportare cumuli più grandi (ma questo ha anche i suoi limiti oltre i cumuli da 16 GB). Esiste anche una JVM commerciale con GC (Azul) migliorato "senza pausa".


4
"alloca grandi quantità di memoria" non gestita "e usala per salvare gli oggetti lì" - non puoi salvare oggetti in pila. Puoi conservare le primitive, puoi avvolgerle in qualsiasi libreria ti piaccia, ma questi non sono Oggetti. I dati posizionati offheap non hanno intestazione di oggetto, non è possibile sincronizzare su di essi, non è possibile fare riferimento ad esso con un campo di riferimento in qualche altro oggetto.
Nitsan Wakart,

41

L'heap è il luogo in memoria in cui vivono gli oggetti allocati dinamicamente. Se lo hai usato, newè nell'heap. Questo è al contrario dello spazio dello stack, che è dove vive la funzione dello stack. Se hai una variabile locale, quel riferimento è nello stack. L'heap di Java è soggetto alla garbage collection e gli oggetti sono utilizzabili direttamente.

L'archiviazione off-heap di EHCache toglie l'oggetto normale dall'heap, lo serializza e lo memorizza come byte in un blocco di memoria gestito da EHCache. È come memorizzarlo su disco ma è ancora nella RAM. Gli oggetti non sono direttamente utilizzabili in questo stato, devono prima essere deserializzati. Inoltre, non soggetto alla raccolta dei rifiuti.


Non è semplicemente ancora nell'heap ma come una forma serializzata?
Pacerier,

1
come lo rende più efficiente?
Pacerier,

2
Ci sono molti modi. Poiché gli oggetti non si trovano più sull'heap Java principale, non sprecano il tempo del Garbage Collector, non frammentano l'heap della JVM e liberano spazio per altri oggetti più utilizzati. Inoltre, poiché sono serializzati e probabilmente non necessari nell'immediato futuro, possono essere compressi, spostati in base alle esigenze o persino trasferiti su disco.
Adam,

1
In Hotspot, il tempo di pausa GC dipende direttamente dalle dimensioni dell'heap. BigMemory offre questo compromesso utilizzando la RAM anziché l'heap, per ridurre al minimo il GC ed evitare il costo di I / O dell'accesso al disco.
Chander Shivdasani,


1

La JVM non sa nulla della memoria off-heap. Ehcache implementa una cache su disco e una cache in memoria.


1

Non al 100%; tuttavia, sembra che l'heap sia un oggetto o un insieme di spazio allocato (su RAM) integrato nella funzionalità del codice Java stesso o più probabilmente dalla stessa ehcache, e il Ram off-heap è il proprio sistema come bene; tuttavia, sembra che questa sia una grandezza più lenta in quanto non è così organizzata, il che significa che potrebbe non utilizzare un heap (che significa un lungo set di spazio di ram), e invece utilizza spazi di indirizzamento diversi probabilmente rendendolo leggermente meno efficiente.

Quindi, naturalmente, il livello inferiore successivo è lo spazio sul disco rigido stesso.

Non uso ehcache, quindi potresti non voler fidarti di me, ma questo è quello che ho raccolto dalla loro documentazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.