Pertanyaan Apakah tumpukan sampah dikumpulkan di Jawa?


Memori heap adalah sampah yang dikumpulkan di Jawa.

Apakah tumpukan sampah dikumpulkan juga?

Bagaimana memori stack direklamasi?


48
2018-03-15 13:42


asal


Jawaban:


Memori pada stack berisi parameter-metode dan variabel lokal (tepatnya: referensi untuk objek dan variabel itu sendiri untuk tipe primitif). Itu akan dihapus secara otomatis jika Anda meninggalkan metode. Jika variabel adalah referensi (ke objek) objek itu sendiri berada di heap dan ditangani oleh garbage collector.

Jadi tumpukan sampah tidak dikumpulkan dengan cara yang sama seperti tumpukan, tetapi tumpukan adalah bentuk manajemen memori otomatis di dalamnya sendiri (yang mendahului pengumpulan sampah).

SEBUAH jawaban yang lebih rinci diberikan oleh Thomas Pornin, lihat itu untuk lebih jelasnya.


33
2018-03-15 13:46



Tumpukannya bukan sampah yang dikumpulkan di Jawa.

Tumpukan yang dialokasikan untuk panggilan metode yang diberikan dibebaskan ketika metode kembali. Karena itu struktur LIFO yang sangat sederhana, tidak perlu pengumpulan sampah.

Satu tempat di mana tumpukan dan pengumpulan sampah berinteraksi adalah referensi pada tumpukan adalah akar GC (yang berarti bahwa mereka adalah referensi akar dari mana reachability ditentukan).


28
2018-03-15 13:46



Tumpukan bisa menjadi sampah yang dikumpulkan. Namun, dalam kebanyakan implementasi JVM, itu ditangani sebagai, baik, "tumpukan", yang menurut definisi menghalangi pengumpulan sampah.

Apa yang kita sebut tumpukan adalah akumulasi dari konteks aktivasi metode: untuk setiap metode yang dipanggil, ini adalah struktur konseptual yang berisi argumen metode, variabel lokal, penunjuk tersembunyi ke konteks untuk metode panggilan, dan slot untuk menyimpan penunjuk instruksi. Konteks aktivasi tidak dapat diakses seperti itu dari bahasa Jawa itu sendiri. Konteks menjadi tidak berguna saat metode keluar (dengan return atau karena pengecualian yang dibuang). Kebetulan bahwa ketika metode A memanggil metode B, dijamin bahwa ketika A mendapatkan kembali kendali, konteks untuk B menjadi tidak berguna. Ini menyiratkan bahwa seumur hidup konteks untuk B adalah subrange dari seumur hidup konteks untuk A. Oleh karena itu, konteks aktivasi (untuk suatu thread tertentu) dapat dialokasikan dengan disiplin LIFO ("Last In, First Out"). Dengan kata yang lebih sederhana, tumpukan: konteks aktivasi baru didorong di atas tumpukan konteks, dan konteks di atas akan menjadi yang pertama untuk dibuang.

Dalam prakteknya, konteks aktivasi (juga disebut bingkai tumpukan) digabung, dalam urutan tumpukan, di area khusus. Area itu diperoleh dari sistem operasi ketika thread dimulai, dan sistem operasi mendapatkannya kembali ketika thread berakhir. Bagian atas tumpukan ditunjuk oleh pointer tertentu, sering terdapat dalam register CPU (ini tergantung pada apakah JVM menafsirkan atau mengkompilasi kode). "Penunjuk ke konteks pemanggil" adalah virtual; konteks pemanggil harus berada tepat di bawah dalam urutan tumpukan. GC tidak campur tangan: area untuk tumpukan dibuat dan direklamasi secara sinkron, dari aktivitas utas itu sendiri. Ini juga cara kerjanya dalam banyak bahasa seperti C, yang tidak memiliki GC sama sekali.

Sekarang tidak ada yang menghalangi implementasi JVM dari melakukan sebaliknya, mis. mengalokasikan konteks aktivasi di heap dan meminta mereka dikumpulkan oleh GC. Ini biasanya tidak dilakukan di Java Virtual Machines karena alokasi tumpukan lebih cepat. Tetapi beberapa bahasa lain perlu melakukan hal-hal seperti itu, terutama yang memainkannya lanjutan saat masih menggunakan GC (mis. Skema dan itu call-with-current-continuation function), karena game semacam itu melanggar aturan LIFO yang dijelaskan di atas.


14
2018-03-16 11:38



Bagian tumpukan memori berfungsi seperti "tumpukan". Saya tahu kedengarannya buruk, tapi itulah cara kerjanya. Data ditambahkan ke atas, di atas satu sama lain (pushed onto the stack) dan secara otomatis dihapus dari atas (popped off the stack) saat program Anda berjalan. Ini bukan sampah yang dikumpulkan - dan itu tidak perlu karena memori itu secara otomatis diambil kembali setelah data dibuang dari tumpukan. Dan ketika saya mengatakan reklamasi, saya tidak bermaksud itu mendapat de-dialokasikan - hanya saja lokasi dalam memori stack di mana data berikutnya akan disimpan menurun, karena data terputus.

Tentu saja itu tidak berarti bahwa Anda tidak perlu khawatir tentang tumpukan itu. Jika Anda menjalankan fungsi rekursif berkali-kali pada akhirnya akan menggunakan semua ruang stack. Hal yang sama jika Anda memanggil banyak fungsi, terutama jika mereka memiliki banyak parameter dan / atau variabel lokal.

Tetapi intinya adalah bahwa memori stack digunakan dan direklamasi sebagai fungsi masuk dan meninggalkan ruang lingkup - secara otomatis. Jadi pada akhir eksekusi program Anda semua memori stack akan bebas dan kemudian dilepaskan kembali ke sistem operasi.


8
2018-03-15 13:50



Jika Anda mengacu pada memori yang digunakan pada tumpukan, itu bukan sampah yang dikumpulkan.
Mesin virtual java menggunakan instruksi bytecode eksplisit untuk cadangan dan melepaskan memori pada stack, instruksi ini dihasilkan oleh kompiler dan mengatur umur primitif seperti int, boolean, double dan referensi objek pada stack.
Ada rencana untuk mengimplementasikan apa yang disebut optimasi panggilan ekor, yang akan menghapus beberapa entri dari stack setelah diketahui bahwa mereka tidak lagi digunakan, tapi saya tidak tahu ada jvm yang sudah mendukung ini.
Jadi tidak ada pengumpulan sampah untuk stack itu sendiri, hanya compiler yang menghasilkan instruksi push dan pop untuk mengelola penggunaan memori.

Tumpukan itu sendiri adalah bagian dari sebuah utas. Tumpukan dialokasikan ketika objek benang dibuat dan sampah yang dikumpulkan setelah thread diakhiri dan objek benang tidak lagi direferensikan.


4
2018-03-18 15:43



Semua objek di Jawa dialokasikan pada heap. (Setidaknya sejauh spesifikasi berjalan, implementasi sebenarnya dapat mengalokasikannya di stack jika mereka secara transparan berperilaku seolah-olah berada di heap.)

Sebenarnya apa yang bisa ditagih agak halus. Jika satu-satunya referensi ke objek dalam satu tumpukan frame, dan dapat ditunjukkan bahwa referensi tidak akan digunakan lagi, maka objek dapat dikumpulkan. Jika objek hanya digunakan untuk membaca bidang, maka bidang yang dibaca dapat dioptimalkan ke depan dan objek yang dikumpulkan lebih awal dari yang Anda harapkan.

Ini biasanya tidak masalah kecuali Anda menggunakan finalisers (atau mungkin References). Dalam hal ini Anda harus berhati-hati dan menggunakan kunci / mudah menguap untuk menegakkan happens-before hubungan.

Ketika thread berhenti, maka biasanya seluruh tumpukan akan dialihkan.


1
2018-03-15 16:14



Segala sesuatu yang terletak di tumpukan diperlakukan sebagai akar global oleh pengumpul sampah. Jadi, ya, Anda pasti bisa mengatakan bahwa tumpukan itu adalah "sampah yang dikumpulkan".


1
2018-03-15 16:23