Di mana bidang primitif disimpan?
Bidang primitif disimpan sebagai bagian dari objek yang dipakai di suatu tempat . Cara termudah untuk memikirkan di mana ini - adalah tumpukan. Namun , ini tidak selalu terjadi. Seperti yang dijelaskan dalam teori dan praktik Java: Legenda kinerja perkotaan, ditinjau kembali :
JVM dapat menggunakan teknik yang disebut analisis melarikan diri, yang dengannya mereka dapat mengatakan bahwa objek tertentu tetap terbatas pada satu utas untuk seluruh masa pakainya, dan masa itu dibatasi oleh masa pakai kerangka tumpukan yang diberikan. Benda-benda seperti itu dapat dengan aman dialokasikan pada tumpukan, bukan tumpukan. Bahkan lebih baik, untuk objek kecil, JVM dapat mengoptimalkan alokasi sepenuhnya dan hanya mengangkat bidang objek ke register.
Jadi, melampaui mengatakan "objek dibuat dan bidang ada di sana juga", orang tidak dapat mengatakan apakah ada sesuatu di tumpukan atau di tumpukan. Perhatikan bahwa untuk objek kecil, berumur pendek, kemungkinan bahwa 'objek' tidak akan ada dalam memori seperti itu dan sebagai gantinya dapat menempatkan bidangnya langsung di register.
Makalah ini diakhiri dengan:
Secara mengejutkan, JVM pandai mencari tahu hal-hal yang kami anggap hanya pengembang yang tahu. Dengan membiarkan JVM memilih antara alokasi tumpukan dan alokasi tumpukan berdasarkan kasus per kasus, kita bisa mendapatkan manfaat kinerja dari alokasi tumpukan tanpa membuat programmer merasa tersinggung apakah akan mengalokasikan pada tumpukan atau pada tumpukan.
Jadi, jika Anda memiliki kode yang terlihat seperti:
void foo(int arg) {
Bar qux = new Bar(arg);
...
}
di mana yang ...
tidak memungkinkan qux
untuk meninggalkan ruang lingkup itu, qux
dapat dialokasikan pada tumpukan sebagai gantinya. Ini sebenarnya adalah kemenangan untuk VM karena itu berarti tidak perlu menjadi sampah yang dikumpulkan - itu akan hilang ketika meninggalkan ruang lingkup.
Lebih lanjut tentang analisis pelarian di Wikipedia. Bagi mereka yang ingin mempelajari makalah, Escape Analysis for Java dari IBM. Bagi mereka yang berasal dari dunia C #, Anda mungkin menemukan The Stack Is an Detail Implementasi dan The Truth About Value Type oleh Eric Lippert bacaan yang baik (mereka berguna untuk tipe Java juga karena banyak konsep dan aspek yang sama atau mirip) . Mengapa .Net buku berbicara tentang alokasi memori tumpukan vs tumpukan? juga masuk ke ini.
Di mengapa tumpukan dan tumpukan
Di atas tumpukan
Jadi, mengapa memiliki tumpukan atau tumpukan sama sekali? Untuk hal-hal yang meninggalkan ruang lingkup, tumpukan bisa mahal. Pertimbangkan kodenya:
void foo(String arg) {
bar(arg);
...
}
void bar(String arg) {
qux(arg);
...
}
void qux(String arg) {
...
}
Parameter juga merupakan bagian dari tumpukan. Dalam situasi yang Anda tidak memiliki tumpukan, Anda akan melewati set nilai penuh pada tumpukan. Ini bagus untuk "foo"
dan string kecil ... tapi apa yang akan terjadi jika seseorang meletakkan file XML besar di string itu. Setiap panggilan akan menyalin seluruh string besar ke tumpukan - dan itu akan sangat sia-sia.
Sebaliknya, lebih baik untuk meletakkan benda-benda yang memiliki kehidupan di luar lingkup langsung (diteruskan ke lingkup lain, terjebak dalam struktur yang dipelihara orang lain, dll ...) ke area lain yang disebut tumpukan.
Di tumpukan
Anda tidak perlu tumpukan. Seseorang dapat, secara hipotetis, menulis bahasa yang tidak menggunakan tumpukan (kedalaman arbitrer). BASIC lama yang saya pelajari di masa muda saya melakukannya, seseorang hanya bisa melakukan 8 level gosub
panggilan dan semua variabel bersifat global - tidak ada tumpukan.
Keuntungan dari stack adalah ketika Anda memiliki variabel yang ada dengan cakupan, ketika Anda meninggalkan cakupan itu, frame tumpukan itu muncul. Itu benar-benar menyederhanakan apa yang ada dan apa yang tidak ada. Program pindah ke prosedur lain, bingkai tumpukan baru; program kembali ke prosedur, dan Anda telah kembali ke prosedur yang melihat lingkup Anda saat ini; program meninggalkan prosedur dan semua item pada stack tidak dapat dialokasikan.
Ini benar-benar membuat hidup mudah bagi orang yang menulis runtime untuk kode untuk menggunakan stack dan heap. Mereka hanya banyak konsep dan cara kerja pada kode yang memungkinkan orang yang menulis kode dalam bahasa dibebaskan dari memikirkannya secara eksplisit.
Sifat stack juga berarti tidak bisa terfragmentasi. Fragmentasi memori adalah masalah nyata dengan heap. Anda mengalokasikan beberapa objek, lalu sampah mengumpulkan yang di tengah, dan kemudian mencoba menemukan ruang untuk yang besar berikutnya untuk dialokasikan. Ini berantakan. Mampu meletakkan barang-barang di tumpukan berarti Anda tidak harus berurusan dengan itu.
Ketika sesuatu sampah dikumpulkan
Ketika sesuatu dikumpulkan, sampah itu hilang. Tapi itu hanya sampah yang dikumpulkan karena sudah dilupakan - tidak ada lagi referensi ke objek dalam program yang dapat diakses dari kondisi program saat ini.
Saya akan menunjukkan bahwa ini adalah penyederhanaan pengumpulan sampah yang sangat besar. Ada banyak pengumpul sampah (bahkan di Jawa - Anda dapat men-tweak pengumpul sampah dengan menggunakan berbagai bendera ( docs ). Ini berperilaku berbeda dan nuansa bagaimana masing-masing melakukan hal-hal agak terlalu dalam untuk jawaban ini. Anda mungkin ingin membaca Dasar - Dasar Pengumpulan Sampah Jawa untuk mendapatkan ide yang lebih baik tentang bagaimana beberapa di antaranya berfungsi.
Yang mengatakan, jika sesuatu dialokasikan pada tumpukan, itu bukan sampah yang dikumpulkan sebagai bagian dari System.gc()
- itu tidak dialokasikan ketika bingkai tumpukan muncul. Jika ada sesuatu di tumpukan, dan direferensikan dari sesuatu di tumpukan, itu tidak akan menjadi sampah yang dikumpulkan saat itu.
Mengapa ini penting?
Sebagian besar, tradisi. Buku-buku teks yang ditulis dan kelas kompilasi dan berbagai bit dokumentasi membuat masalah besar tentang tumpukan dan tumpukan.
Namun, mesin virtual saat ini (JVM dan sejenisnya) telah berusaha keras untuk mencoba menyembunyikan ini dari programmer. Kecuali jika Anda kehabisan satu dan yang lain dan perlu tahu mengapa (bukan hanya menambah ruang penyimpanan dengan tepat), itu tidak terlalu menjadi masalah.
Objek berada di suatu tempat dan berada di tempat di mana ia dapat diakses dengan benar dan cepat untuk jumlah waktu yang tepat yang ada. Jika ada di tumpukan atau tumpukan - itu tidak masalah.