Bagaimana kumpulan memori java dibagi?

224

Saat ini saya sedang memonitor aplikasi Java dengan jconsole. Tab memori memungkinkan Anda memilih di antara:

Heap Memory Usage
Non-Heap Memory Usage
Memory Pool “Eden Space”
Memory Pool “Survivor Space”
Memory Pool “Tenured Gen”
Memory Pool “Code Cache”
Memory Pool “Perm Gen”

Apa perbedaan di antara mereka?

Dani Cricco
sumber
Dengan asumsi bahwa Anda menggunakan Sun JDK, jawaban terbaik akan ditemukan dalam dokumentasi mereka: Tuning Garbage Collection (JDK 1.5) dan FAQ Pengumpulan Sampah (JDK 1.4)
kdgregory

Jawaban:

327

Tumpukan memori

Memori tumpukan adalah area data runtime dari mana Java VM mengalokasikan memori untuk semua instance kelas dan array. Tumpukan mungkin ukuran tetap atau variabel. Pengumpul sampah adalah sistem manajemen memori otomatis yang mengambil kembali memori tumpukan untuk objek.

  • Eden Space : Kolam dari mana memori awalnya dialokasikan untuk sebagian besar objek.

  • Survivor Space : Kolam yang berisi benda-benda yang selamat dari pengumpulan sampah ruang Eden.

  • Tenured Generation atau Old Gen : Kelompok yang berisi objek yang telah ada selama beberapa waktu di ruang survivor

Memori non-tumpukan

Memori non-heap mencakup area metode yang digunakan bersama di antara semua utas dan memori yang diperlukan untuk pemrosesan internal atau optimalisasi untuk Java VM. Ini menyimpan struktur per-kelas seperti kumpulan konstanta runtime, data bidang dan metode, dan kode untuk metode dan konstruktor. Area metode secara logis merupakan bagian dari heap tetapi, tergantung pada implementasinya, Java VM mungkin tidak mengumpulkan atau memadatkannya. Seperti memori tumpukan, area metode mungkin ukuran tetap atau variabel. Memori untuk area metode tidak perlu bersebelahan.

  • Generasi Permanen : Kumpulan yang berisi semua data reflektif dari mesin virtual itu sendiri, seperti objek kelas dan metode. Dengan Java VM yang menggunakan berbagi data kelas, generasi ini dibagi menjadi area baca-saja dan baca-tulis.

  • Cache Kode : HotSpot Java VM juga menyertakan kode cache, berisi memori yang digunakan untuk kompilasi dan penyimpanan kode asli.

Berikut beberapa dokumentasi tentang cara menggunakan Jconsole .

dfa
sumber
4
Saya tidak yakin @dfa sepenuhnya benar karena Java Virtual Machine Specification dengan jelas menyatakan: "Meskipun area metode secara logis bagian dari heap, implementasi sederhana mungkin memilih untuk tidak mengumpulkan sampah atau memadatkannya." Namun jelas bahwa jconsole menunjukkan Cache Kode dan Generasi Permanen sebagai Non-Heap, yang tampaknya bertentangan dengan spesifikasi. Adakah yang bisa memberikan lebih banyak klarifikasi tentang kontradiksi ini?
James Bloom
@ JamesBloom - Saya ingin tahu hal yang sama. Meskipun definisi dasar menyatakan kolam memori mana yang termasuk tipe (heap / non-heap), itu bisa berubah apakah menyatakan secara eksplisit?
Umang Desai
2
dokumen ini secara semula berasal dari: docs.intergral.com/pages/viewpage.action?pageId=22478944 Dokumen ini berisi beberapa informasi bagus lainnya tentang JVM, yang patut ditelusuri
Steve Siebert
1
Meskipun ada banyak masalah, sebenarnya itu bukan jawaban yang berarti. Misalnya, apa yang dimaksud "benda yang selamat dari pengumpulan sampah di ruang Eden"? Apakah benda-benda ini dipindahkan ke Ruang Survivor dari Eden setelah selamat, atau ruang mereka di Eden dianggap sebagai ruang Survivor? Dan bagaimana dengan pengumpulan sampah di kolam selain ruang Eden, apakah itu terjadi? Sama sekali tidak jelas.
Mikhail Batcer
dan jangan lupa tumpukan (di sisi non-heap) :)
Seekor ompong
70

Kata kunci baru mengalokasikan memori pada tumpukan Java. Tumpukan adalah kumpulan memori utama, dapat diakses oleh seluruh aplikasi. Jika tidak ada cukup memori yang tersedia untuk dialokasikan untuk objek itu, JVM mencoba untuk mengambil kembali sebagian memori dari tumpukan dengan pengumpulan sampah. Jika masih tidak mendapatkan cukup memori, OutOfMemoryError dilempar, dan JVM keluar.

Tumpukan dibagi menjadi beberapa bagian yang berbeda, yang disebut generasi. Karena objek bertahan lebih banyak dari pengumpulan sampah, mereka dipromosikan ke generasi yang berbeda. Generasi yang lebih tua tidak sering mengumpulkan sampah. Karena benda-benda ini telah terbukti berumur panjang, mereka cenderung mengumpulkan sampah.

Ketika objek pertama kali dibangun, mereka dialokasikan di Ruang Eden. Jika mereka selamat dari pengumpulan sampah, mereka dipromosikan ke Ruang Selamat, dan jika mereka hidup cukup lama di sana, mereka dialokasikan ke Generasi Bertenor. Generasi ini lebih jarang mengumpulkan sampah.

Ada juga generasi keempat, yang disebut Generasi Permanen, atau PermGen. Objek yang berada di sini tidak memenuhi syarat untuk menjadi sampah yang dikumpulkan, dan biasanya berisi keadaan tidak berubah yang diperlukan untuk menjalankan JVM, seperti definisi kelas dan kumpulan konstanta String. Perhatikan bahwa ruang PermGen direncanakan akan dihapus dari Java 8, dan akan diganti dengan ruang baru yang disebut Metaspace, yang akan disimpan dalam memori asli. referensi :http://www.programcreek.com/2013/04/jvm-run-time-data-areas/

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Pythoner
sumber
Diagram terlihat sangat jelas ... Apakah ini valid untuk algoritma GC apa pun. G1 memiliki set yang berbeda.
Venkateswara Rao
@Pythoner Saya pikir bendera ungu gelap seharusnya -XX:PermSizedan tidak -XX:MaxPermSizeseperti yang sudah didefinisikan di atas itu.
Anurag
35

Dengan Java8, wilayah non heap tidak lagi berisi PermGen tetapi Metaspace, yang merupakan perubahan besar di Java8, seharusnya menyingkirkan kesalahan memori dengan java karena ukuran metaspace dapat ditingkatkan tergantung pada ruang yang dibutuhkan oleh jvm untuk data kelas.

pengguna2767149
sumber
1
Sebenarnya, ada ruang metaspace dan ruang kelas: docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/…
mrswadge
23

Java Heap Memory adalah bagian dari memori yang dialokasikan untuk JVM oleh Sistem Operasi.

Objek berada di area yang disebut heap. Tumpukan dibuat ketika JVM dimulai dan dapat menambah atau mengurangi ukuran saat aplikasi berjalan. Ketika tumpukan menjadi penuh, sampah dikumpulkan.

masukkan deskripsi gambar di sini

Anda dapat menemukan detail lebih lanjut tentang Eden Space, Survivor Space, Tenured Space dan Permanent Generation di bawah pertanyaan SE:

Generasi muda, Bertenor dan Perm

PermGen telah diganti dengan Metaspace sejak rilis Java 8.

Mengenai pertanyaan Anda:

  1. Eden Space, Survivor Space, Tenured Space adalah bagian dari tumpukan memori
  2. Metaspace dan Code Cache adalah bagian dari memori non-heap.

Codecache: Java Virtual Machine (JVM) menghasilkan kode asli dan menyimpannya di area memori yang disebut codecache. JVM menghasilkan kode asli untuk berbagai alasan, termasuk untuk loop interpreter yang dihasilkan secara dinamis, Java Native Interface (JNI) stubs, dan untuk metode Java yang dikompilasi ke dalam kode asli oleh kompiler just-in-time (JIT). JIT sejauh ini merupakan pengguna codecache terbesar.

Ravindra babu
sumber