Perbedaan antara "on-heap" dan "off-heap"

146

Ehcache berbicara tentang memori on-heap dan off-heap. Apa bedanya? Argumen JVM apa yang digunakan untuk mengkonfigurasinya?

Synesso
sumber
Untuk cara menggunakan memori tidak
bertumpukan

Jawaban:

169

Toko on-heap merujuk ke objek yang akan hadir di tumpukan Jawa (dan juga tunduk pada GC). Di sisi lain, toko off-heap mengacu pada objek (serial) yang dikelola oleh EHCache, tetapi disimpan di luar heap (dan juga tidak tunduk pada GC). Karena toko off-heap terus dikelola dalam memori, ini sedikit lebih lambat daripada toko on-heap, tetapi masih lebih cepat dari toko disk.

Detail internal yang terlibat dalam manajemen dan penggunaan toko di luar tumpukan tidak begitu jelas dalam tautan yang diposting di pertanyaan, jadi sebaiknya lihat detail Terracotta BigMemory , yang digunakan untuk mengelola off-disk toko. BigMemory (toko off-heap) akan digunakan untuk menghindari overhead GC pada heap yang beberapa Megabytes atau Gigabytes besar. BigMemory menggunakan ruang alamat memori proses JVM, melalui ByteBuffers langsung yang tidak tunduk pada GC tidak seperti objek Java asli lainnya.

Vineet Reynolds
sumber
18
+1 untuk menyebutkan ByteBuffers langsung untuk eksplorasi lebih lanjut;)
Max
3
ByteBuffers langsung menawarkan akses ke memori yang tidak dikelola, tetapi mereka sendiri tunduk pada GC (sebagai lawan dari data yang mereka tunjukkan). Ini penting karena ByteBuffer langsung (jenis ByteBuffer.allocateDirect, bukan jenis MMap) akan dikumpulkan oleh GC dan ketika dikumpulkan, Deallocater akan dipicu, secara efektif mengumpulkan memori yang tidak dikelola juga.
Nitsan Wakart
Menggunakan Unsafe untuk mengalokasikan objek sepertinya memiliki kinerja baca dan tulis yang jauh lebih baik daripada Onheap / DirectByteBuffers / ByteBuffers. ashkrit.blogspot.com/2013/07/...
Joe C
98

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

Apa itu Heap-Offloading?

Biasanya semua objek non-temporer yang Anda alokasikan dikelola oleh pengumpul sampah java. Meskipun VM melakukan pekerjaan yang layak melakukan pengumpulan sampah, pada titik tertentu VM harus melakukan apa yang disebut 'GC Penuh'. GC lengkap melibatkan pemindaian Heap yang dialokasikan lengkap, yang berarti GC jeda / perlambatan sebanding dengan ukuran tumpukan aplikasi. Jadi jangan percaya orang mengatakan 'Memory is Cheap'. Dalam konsumsi memori java sakit kinerja. Selain itu, Anda mungkin mendapatkan jeda penting menggunakan ukuran tumpukan> 1 Gb. Ini bisa menjijikkan jika Anda memiliki hal-hal yang hampir real-time terjadi, dalam sebuah cluster atau grid proses java mungkin menjadi tidak responsif dan bisa jatuh dari cluster.

Namun, aplikasi server saat ini (sering dibangun di atas kerangka kerja yang mengasyikkan ;-)) dengan mudah membutuhkan tumpukan jauh melebihi 4Gb.

Salah satu solusi untuk persyaratan memori ini, adalah 'melepas' bagian-bagian objek ke tumpukan non-java (langsung dialokasikan dari OS). Untungnya java.nio menyediakan kelas untuk secara langsung mengalokasikan / membaca dan menulis potongan memori 'tidak dikelola' (bahkan file yang dipetakan memori).

Jadi seseorang dapat mengalokasikan sejumlah besar memori 'tidak terkelola' dan menggunakannya untuk menyimpan objek di sana. Untuk menyimpan objek yang sewenang-wenang ke dalam memori yang tidak dikelola, solusi yang paling memungkinkan adalah penggunaan Serialisasi. Ini berarti aplikasi membuat serialisasi objek ke dalam memori offheap, nanti objek dapat dibaca menggunakan deserialization.

Ukuran heap yang dikelola oleh Java VM bisa dijaga tetap kecil, jadi GC jeda ada di millis, semua orang senang, pekerjaan selesai.

Jelas, bahwa kinerja buffer off-heap seperti itu sebagian besar tergantung pada kinerja implementasi serialisasi. Berita bagus: untuk beberapa alasan FST-serialisasi cukup cepat :-).

Skenario penggunaan sampel:

  • Cache sesi dalam aplikasi server. Gunakan file yang dipetakan memori untuk menyimpan gigabytes sesi pengguna (tidak aktif). Setelah pengguna masuk ke aplikasi Anda, Anda dapat dengan cepat mengakses data terkait pengguna tanpa harus berurusan dengan database.
  • Caching hasil komputasi (kueri, halaman html, ..) (hanya berlaku jika perhitungan lebih lambat daripada deserialisasi objek hasil c).
  • sangat sederhana dan ketahanan cepat menggunakan file yang dipetakan memori

Sunting: Untuk beberapa skenario, seseorang dapat memilih algoritma Pengumpulan Sampah yang lebih canggih seperti ConcurrentMarkAndSweep atau G1 untuk mendukung tumpukan yang lebih besar (tetapi ini juga memiliki batas melebihi tumpukan 16GB). Ada juga JVM komersial dengan peningkatan 'jeda' GC (Azul) tersedia.

R.Moeller
sumber
4
"alokasikan sejumlah besar memori 'tidak terkelola' dan gunakan ini untuk menyimpan objek di sana" - Anda tidak dapat menyimpan Object ofheap. Anda dapat menyimpan primitif, Anda dapat membungkusnya di perpustakaan apa pun yang Anda suka, tetapi ini bukan Objects. Data yang Anda tempatkan tidak memiliki header objek, Anda tidak dapat menyinkronkannya, Anda tidak bisa merujuknya dengan bidang referensi di beberapa objek lain.
Nitsan Wakart
41

Tumpukan adalah tempat di memori tempat objek Anda yang dialokasikan secara dinamis hidup. Jika Anda menggunakan newmaka ada di tumpukan. Itu berlawanan dengan ruang stack, yang merupakan tempat fungsi stack hidup. Jika Anda memiliki variabel lokal maka referensi itu ada di tumpukan. Tumpukan Jawa tunduk pada pengumpulan sampah dan benda-benda dapat digunakan secara langsung.

Penyimpanan off-heap EHCache menghilangkan objek reguler Anda dari heap, membuat serial, dan menyimpannya sebagai byte di dalam sepotong memori yang dikelola EHCache. Ini seperti menyimpannya ke disk tetapi masih dalam RAM. Objek tidak secara langsung dapat digunakan dalam keadaan ini, mereka harus dideeralisasi terlebih dahulu. Juga tidak dikenakan pengumpulan sampah.

Adam
sumber
Bukankah itu masih dalam tumpukan tetapi sebagai bentuk serial?
Pacerier
1
bagaimana itu membuatnya lebih efisien?
Pacerier
2
Ada banyak cara. Karena objek tidak lagi di tumpukan Jawa utama mereka tidak membuang waktu pengumpul sampah, mereka tidak memecah tumpukan JVM dan mereka membebaskan ruang untuk objek lain yang lebih banyak digunakan. Juga, karena mereka serial dan kemungkinan tidak diperlukan dalam waktu dekat mereka dapat dikompresi, dipindahkan sesuai kebutuhan, atau bahkan dipindahkan ke disk.
Adam
1
Di Hotspot, waktu jeda GC tergantung langsung pada ukuran tumpukan. BigMemory memberikan trade off ini dengan menggunakan RAM alih-alih tumpukan, untuk menjaga GC jeda minimum dan menghindari biaya IO dari akses disk.
Chander Shivdasani
18

Dalam gambaran singkat

Singkatnya Java On / Off Heap storage

kredit gambar


Gambar rinci

Java On / Off Heap storage secara detail

kredit gambar

mrsrinivas
sumber
Apakah mematikan memori yang dikendalikan oleh -xmx? Yang biru adalah Gen Tua atau tidak aktif?
Himanshu Ahire
Tidak. Ini ruang yang tidak digunakan di heap, itu akan diisi ketika banyak objek yang dibuat di heap.
mrsrinivas
1

JVM tidak tahu apa-apa tentang memori di luar tumpukan. Ehcache mengimplementasikan cache di-disk dan juga cache di-memori.

Gatkin
sumber
1

Tidak 100%; Namun, sepertinya heap adalah objek atau set ruang yang dialokasikan (pada RAM) yang dibangun ke dalam fungsi kode baik Java itu sendiri atau fungsionalitas yang lebih mungkin dari ehcache itu sendiri, dan Ram off-heap ada sistem sendiri sebagai baik; namun, sepertinya ini satu kali lebih lambat karena tidak terorganisir, artinya tidak boleh menggunakan heap (artinya satu set panjang ruang ram), dan alih-alih menggunakan ruang alamat yang berbeda yang sepertinya membuatnya sedikit kurang efisien.

Maka tentu saja tingkat berikutnya yang lebih rendah adalah ruang hard-drive itu sendiri.

Saya tidak menggunakan ehcache, jadi Anda mungkin tidak ingin mempercayai saya, tetapi itulah yang saya kumpulkan dari dokumentasi mereka.

msj121
sumber