Pengurusan Memori dalam Soalan Temuduga Java (+ Jawapan)

Artikel ini adalah sebahagian daripada siri: • Pertanyaan Temuduga Koleksi Java

• Soalan Temuduga Sistem Jenis Java

• Pertanyaan Temuduga Bersama Java (+ Jawapan)

• Soalan Temuduga Struktur dan Permulaan Kelas Java

• Soalan Temuduga Java 8 (+ Jawapan)

• Pengurusan Memori dalam Soalan Temuduga Java (+ Jawapan) (artikel semasa) • Soalan Temuduga Generik Java (+ Jawapan)

• Soalan Temuduga Kawalan Aliran Java (+ Jawapan)

• Soalan Temuduga Pengecualian Java (+ Jawapan)

• Soalan Temuduga Anotasi Java (+ Jawapan)

• Soalan Temuduga Kerangka Musim Bunga Teratas

1. Pengenalan

Dalam artikel ini, kita akan meneroka beberapa persoalan pengurusan memori yang sering muncul semasa wawancara pembangun Java. Pengurusan memori adalah kawasan yang tidak begitu banyak pengembangnya kenal.

Sebenarnya, pembangun pada amnya tidak perlu berurusan dengan konsep ini secara langsung - kerana JVM mengurus perincian yang menarik. Kecuali ada sesuatu yang salah, pembangun berpengalaman mungkin tidak mempunyai maklumat yang tepat mengenai pengurusan memori di hujung jari mereka.

Sebaliknya, konsep-konsep ini sebenarnya cukup lazim dalam temu bual - jadi mari kita langsung masuk.

2. Soalan

S1. Apa Arti Pernyataan "Memori Dikelola di Jawa"?

Memori adalah sumber utama yang diperlukan oleh aplikasi untuk berjalan dengan berkesan dan seperti sumber mana pun, kekurangan. Oleh itu, peruntukan dan penyahpindahannya ke dan dari aplikasi atau bahagian aplikasi yang berbeza memerlukan banyak perhatian dan pertimbangan.

Namun, di Java, pemaju tidak perlu secara eksplisit mengalokasikan dan mengalihkan memori - JVM dan lebih khusus lagi Pengumpul Sampah - mempunyai tugas untuk menangani peruntukan memori sehingga pemaju tidak perlu.

Ini bertentangan dengan apa yang berlaku dalam bahasa seperti C di mana pengaturcara mempunyai akses langsung ke memori dan secara harfiah merujuk sel memori dalam kodnya, sehingga banyak ruang untuk kebocoran memori.

S2. Apa itu Pengumpulan Sampah dan Apa Kelebihannya?

Pengumpulan sampah adalah proses melihat memori timbunan, mengenal pasti objek mana yang digunakan dan yang tidak, dan menghapus objek yang tidak digunakan.

Objek yang digunakan, atau objek yang dirujuk, bermaksud bahawa sebahagian daripada program anda masih mengekalkan penunjuk ke objek tersebut. Objek yang tidak digunakan, atau objek yang tidak dirujuk, tidak lagi dirujuk oleh mana-mana bahagian program anda. Jadi memori yang digunakan oleh objek yang tidak dirujuk dapat diambil semula.

Kelebihan terbesar pengumpulan sampah ialah membuang beban peruntukan / pembuangan memori manual dari kami sehingga kami dapat menumpukan perhatian untuk menyelesaikan masalah yang dihadapi.

S3. Adakah Kekurangan Pengumpulan Sampah?

Ya. Setiap kali pengumpul sampah berjalan, ia akan mempengaruhi prestasi aplikasi. Ini kerana semua utas lain dalam aplikasi harus dihentikan untuk membolehkan benang pengutip sampah melakukan kerja dengan berkesan.

Bergantung pada keperluan aplikasi, ini boleh menjadi masalah sebenar yang tidak dapat diterima oleh pelanggan. Walau bagaimanapun, masalah ini dapat dikurangkan atau bahkan dihilangkan melalui pengoptimuman yang mahir dan penyesuaian sampah dan menggunakan algoritma GC yang berbeza.

S4. Apa Arti Istilah “Stop-The-World”?

Apabila benang pengutip sampah berjalan, utas lain dihentikan, yang bermaksud aplikasi dihentikan seketika. Ini serupa dengan pembersihan rumah atau pengasapan di mana penghuni dilarang masuk sehingga prosesnya selesai.

Bergantung pada keperluan aplikasi, pengumpulan sampah "menghentikan dunia" dapat menyebabkan pembekuan yang tidak dapat diterima. Inilah sebabnya mengapa penting untuk melakukan penalaan pengumpul sampah dan pengoptimuman JVM supaya pembekuan yang dihadapi sekurang-kurangnya dapat diterima.

S5. Apa itu Tumpukan dan Tumpukan? Apa yang Disimpan dalam Setiap Struktur Memori Ini, dan Bagaimana Mereka Berkaitan?

Tumpukan adalah bahagian memori yang mengandungi maklumat mengenai panggilan kaedah bersarang turun ke kedudukan semasa dalam program. Ini juga berisi semua pemboleh ubah tempatan dan rujukan ke objek di timbunan yang ditentukan dalam kaedah yang sedang dijalankan.

Struktur ini membolehkan runtime kembali dari kaedah mengetahui alamat dari mana ia dipanggil, dan juga membersihkan semua pemboleh ubah tempatan setelah keluar dari kaedah tersebut. Setiap utas mempunyai timbunannya sendiri.

Tumpukan adalah sebilangan besar memori yang dimaksudkan untuk peruntukan objek. Apabila anda membuat objek dengan kata kunci baru , ia akan diperuntukkan di timbunan. Walau bagaimanapun, rujukan ke objek ini terdapat di timbunan.

S6. Apakah Pengumpulan Sampah Generasi dan Apa yang Menjadikannya Pendekatan Pengumpulan Sampah yang Popular?

Pengumpulan sampah generasi dapat didefinisikan secara longgar sebagai strategi yang digunakan oleh pengumpul sampah di mana timbunan dibahagikan kepada beberapa bahagian yang disebut generasi, yang masing-masing akan menyimpan objek sesuai dengan "usia" mereka di timbunan.

Setiap kali pengumpul sampah berjalan, langkah pertama dalam proses ini disebut penandaan. Di sinilah pengumpul sampah mengenal pasti kepingan memori yang digunakan dan yang tidak. Ini boleh menjadi proses yang sangat memakan waktu jika semua objek dalam sistem mesti diimbas.

Oleh kerana semakin banyak objek diperuntukkan, senarai objek tumbuh dan berkembang sehingga membawa kepada masa pengumpulan sampah yang lebih lama dan lama. Walau bagaimanapun, analisis empirik aplikasi menunjukkan bahawa kebanyakan objek berumur pendek.

Dengan pengumpulan sampah generasi, objek dikelompokkan berdasarkan "usia" mereka dari segi berapa banyak kitaran pengumpulan sampah yang mereka selamatkan. Dengan cara ini, sebahagian besar karya tersebar di pelbagai kitaran pengumpulan kecil dan utama.

Hari ini, hampir semua pengutip sampah adalah generasi. Strategi ini sangat popular kerana, dari masa ke masa, ia terbukti menjadi penyelesaian yang optimum.

S7. Huraikan secara terperinci Bagaimana Pengumpulan Sampah Generasi Berfungsi

Untuk memahami dengan betul bagaimana pengumpulan sampah generasi, penting untuk diingat terlebih dahulu bagaimana timbunan Java disusun untuk memudahkan pengumpulan sampah generasi.

Timbunan dibahagikan kepada ruang atau generasi yang lebih kecil. Ruang-ruang ini adalah Generasi Muda, Generasi Tua atau Tenured, dan Generasi Kekal.

Yang tuan rumah generasi muda kebanyakan objek baru diwujudkan . Kajian empirik kebanyakan aplikasi menunjukkan bahawa sebilangan besar objek cepat berumur pendek dan oleh itu, segera menjadi layak untuk dikumpulkan. Oleh itu, objek baru memulakan perjalanan mereka ke sini dan hanya "dipromosikan" ke ruang generasi lama setelah mereka mencapai "usia" tertentu.

Istilah "usia" dalam pengumpulan sampah generasi merujuk kepada jumlah kitaran pengumpulan objek yang telah bertahan .

Ruang generasi muda dibahagikan lagi kepada tiga ruang: ruang Eden dan dua ruang selamat seperti Survivor 1 (s1) dan Survivor 2 (s2).

Yang lama tuan rumah generasi objek yang telah hidup dalam ingatan lebih lama daripada "umur" tertentu . Objek yang selamat dari pengumpulan sampah dari generasi muda dipromosikan ke ruang ini. Secara amnya lebih besar daripada generasi muda. Oleh kerana saiznya lebih besar, pengumpulan sampah lebih mahal dan jarang berlaku berbanding generasi muda.

The generasi kekal atau lebih biasanya dipanggil, PermGen, mengandungi metadata dikehendaki oleh JVM untuk menggambarkan kelas dan kaedah yang digunakan dalam permohonan itu. Ini juga berisi kumpulan tali untuk menyimpan tali yang dilekatkan. Ia dihuni oleh JVM pada waktu berjalan berdasarkan kelas yang digunakan oleh aplikasi. Di samping itu, kelas dan kaedah perpustakaan platform boleh disimpan di sini.

Pertama, sebarang objek baru diperuntukkan ke ruang Eden . Kedua-dua ruang selamat mula kosong. Apabila ruang Eden penuh, pengumpulan sampah kecil dicetuskan. Objek yang dirujuk dipindahkan ke ruang selamat pertama. Objek yang tidak dirujuk dihapuskan.

Semasa GC kecil seterusnya, perkara yang sama berlaku di ruang Eden. Objek yang tidak dirujuk dihapuskan dan objek yang dirujuk dipindahkan ke ruang yang masih hidup. Namun, dalam kes ini, mereka dipindahkan ke ruang bertahan kedua (S2).

Sebagai tambahan, objek dari GC minor terakhir di ruang selamat pertama (S1) telah meningkat usia dan dipindahkan ke S2. Setelah semua objek yang masih hidup dipindahkan ke S2, ruang S1 dan Eden akan dibersihkan. Pada ketika ini, S2 mengandungi objek dengan usia yang berbeza.

Pada GC minor seterusnya, proses yang sama diulang. Namun kali ini ruang selamat bertukar. Objek yang dirujuk dipindahkan ke S1 dari Eden dan S2. Objek yang selamat berumur. Eden dan S2 dibersihkan.

Selepas setiap kitaran pengumpulan sampah kecil, usia setiap objek diperiksa. Mereka yang telah mencapai usia sewenang-wenang tertentu, misalnya, 8, dipromosikan dari generasi muda ke generasi tua atau lama. Untuk semua kitaran GC kecil berikutnya, objek akan terus dipromosikan ke ruang generasi lama.

Ini cukup melengkapkan proses pengumpulan sampah pada generasi muda. Akhirnya, pengumpulan sampah utama akan dilakukan pada generasi lama yang membersihkan dan memadatkan ruang tersebut. Untuk setiap GC utama, terdapat beberapa GC kecil.

S8. Bilakah Objek Sesuai untuk Memungut Sampah? Huraikan Bagaimana Gc Mengumpulkan Objek yang Layak?

Objek menjadi layak untuk pengumpulan Sampah atau GC jika tidak dapat dicapai dari benang langsung atau dengan rujukan statik.

Kes yang paling mudah bagi objek yang layak untuk pengumpulan sampah adalah jika semua rujukannya batal. Pergantungan siklik tanpa rujukan luaran langsung juga layak untuk GC. Oleh itu, jika objek A merujuk objek B dan objek B merujuk objek A dan mereka tidak mempunyai rujukan langsung lain, maka kedua-dua Objek A dan B akan layak untuk pengumpulan sampah.

Kes lain yang jelas adalah apabila objek induk diatur ke nol. Apabila objek dapur secara dalaman merujuk objek peti sejuk dan objek sinki, dan objek dapur diatur ke nol, kedua-dua peti sejuk dan sink akan memenuhi syarat untuk pengumpulan sampah di samping dapur induk mereka.

S9. Bagaimana Anda Mencetuskan Pengumpulan Sampah dari Kod Java?

Anda, sebagai programmer Java, tidak dapat memaksa pengumpulan sampah di Java ; ia hanya akan mencetuskan jika JVM berpendapat ia memerlukan pengumpulan sampah berdasarkan ukuran timbunan Java.

Sebelum mengeluarkan objek dari benang pengumpulan sampah memori, gunakan kaedah menyelesaikan () objek itu dan memberi peluang untuk melakukan pembersihan apa pun yang diperlukan. Anda juga boleh menggunakan kaedah kod objek ini, namun tidak ada jaminan bahawa pengumpulan sampah akan terjadi ketika anda memanggil kaedah ini.

Selain itu, terdapat kaedah seperti System.gc () dan Runtime.gc () yang digunakan untuk menghantar permintaan pengumpulan sampah ke JVM tetapi tidak dijamin bahawa pengumpulan sampah akan berlaku.

S10. Apa Yang Terjadi Apabila Tidak Ada Ruang Tumpukan Yang Cukup untuk Menampung Penyimpanan Objek Baru?

Sekiranya tidak ada ruang memori untuk membuat objek baru di Heap, Java Virtual Machine membuang OutOfMemoryError atau lebih khusus ruang java.lang.OutOfMemoryError .

S11. Adakah Kemungkinan untuk “Membangkitkan Semula” Objek yang Layak untuk Pengumpulan Sampah?

Apabila objek layak untuk pengumpulan sampah, GC harus menjalankan kaedah menyelesaikannya . The Finalize kaedah dijamin untuk menjalankan hanya sekali, sekali gus GC bendera objek itu sebagai muktamad dan memberikan rehat yang sehingga kitaran seterusnya.

Dalam metode finalisasi Anda secara teknis dapat "menghidupkan kembali" objek, misalnya, dengan menetapkannya ke medan statis . Objek itu akan hidup semula dan tidak layak untuk pengumpulan sampah, jadi GC tidak akan mengumpulkannya pada kitaran berikutnya.

Objek itu, bagaimanapun, akan ditandai sebagai diselesaikan, jadi ketika ia akan layak lagi, metode final tidak akan dipanggil. Pada hakikatnya, anda boleh mengubah helah "kebangkitan" ini hanya sekali seumur hidup objek. Berhati-hatilah bahawa peretasan jelek ini harus digunakan hanya jika anda benar-benar tahu apa yang anda lakukan - namun, memahami trik ini memberi sedikit gambaran tentang bagaimana GC berfungsi.

S12. Huraikan Rujukan yang Kuat, Lemah, Lembut dan Hantu dan Peranannya dalam Pengumpulan Sampah.

Sejauh memori dikendalikan di Java, seorang jurutera mungkin perlu melakukan pengoptimuman sebanyak mungkin untuk meminimumkan latensi dan memaksimumkan throughput, dalam aplikasi kritis. Sejauh mustahil untuk dikendalikan secara eksplisit ketika pengumpulan sampah dipicu di JVM, adalah mungkin untuk mempengaruhi bagaimana ia terjadi mengenai objek yang telah kita buat.

Java memberi kita objek rujukan untuk mengawal hubungan antara objek yang kita buat dan pengumpul sampah.

Secara lalai, setiap objek yang kami buat dalam program Java sangat dirujuk oleh pemboleh ubah:

StringBuilder sb = new StringBuilder();

Dalam coretan di atas, kata kunci baru membuat objek StringBuilder baru dan menyimpannya di timbunan. Pemboleh ubah sb kemudian menyimpan rujukan kuat terhadap objek ini. Apa maksudnya untuk pengutip sampah adalah bahawa objek StringBuilder tertentu tidak layak untuk dikumpulkan sama sekali kerana rujukan kuat yang dipegang oleh sb . Cerita hanya berubah apabila kita membatalkan sb seperti ini:

sb = null;

Setelah memanggil baris di atas, objek tersebut akan layak untuk dikumpulkan.

Kita boleh mengubah hubungan antara objek dan pengumpul sampah dengan membungkusnya secara eksplisit ke dalam objek rujukan lain yang terletak di dalam pakej java.lang.ref .

A rujukan lembut boleh diwujudkan untuk objek di atas seperti ini:

StringBuilder sb = new StringBuilder(); SoftReference sbRef = new SoftReference(sb); sb = null;

Dalam coretan di atas, kami telah membuat dua rujukan ke objek StringBuilder . Baris pertama membuat sb rujukan yang kuat dan baris kedua membuat sbRef rujukan lembut . Baris ketiga harus menjadikan objek layak untuk dikumpulkan tetapi pengumpul sampah akan menangguhkan pengumpulannya kerana sbRef .

Cerita hanya akan berubah apabila ingatan menjadi sesak dan JVM berada di ambang kesilapan membuang OutOfMemory . Dengan kata lain, objek dengan hanya rujukan lembut dikumpulkan sebagai jalan terakhir untuk memulihkan memori.

A rujukan lemah boleh diwujudkan dengan cara yang sama menggunakan WeakReference kelas. Apabila sb diatur ke nol dan objek StringBuilder hanya mempunyai rujukan yang lemah, pengumpul sampah JVM sama sekali tidak akan berkompromi dan segera mengumpulkan objek tersebut pada kitaran seterusnya.

A rujukan hantu adalah sama dengan rujukan yang lemah dan objek dengan rujukan hantu hanya akan diambil tanpa menunggu. Walau bagaimanapun, rujukan hantu dimuat sebaik sahaja objeknya dikumpulkan. Kami dapat mengundi antrian rujukan untuk mengetahui dengan tepat kapan objek itu dikumpulkan.

S13. Anggaplah Kita Mempunyai Rujukan Pekeliling (Dua Objek Yang Merujuk Satu sama Lain). Mungkinkah Sepasang Objek Itu Layak untuk Pengumpulan Sampah dan Mengapa?

Ya, sepasang objek dengan rujukan bulat dapat memenuhi syarat untuk pengumpulan sampah. Ini kerana cara pengumpul sampah Java menangani rujukan pekeliling. Ia menganggap objek hidup bukan ketika ada rujukan padanya, tetapi ketika dapat dicapai dengan menavigasi grafik objek mulai dari beberapa akar pengumpulan sampah (pemboleh ubah tempatan dari utas hidup atau medan statik). Sekiranya sepasang objek dengan rujukan bulat tidak dapat dijangkau dari akar mana pun, ia dianggap layak untuk pengumpulan sampah.

S14. Bagaimana Rentetan Diwakili dalam Memori?

Contoh String di Java adalah objek dengan dua bidang: medan nilai char [] dan medan hash int . Yang nilai medan adalah pelbagai aksara mewakili rentetan itu sendiri, dan hash bidang mengandungi Kodcincang daripada rentetan yang dimulakan dengan sifar, dikira semasa pertama Kodcincang () panggilan dan cache sejak itu. Sebagai kes tepi yang ingin tahu, jika hashCode tali mempunyai nilai sifar, ia harus dikira semula setiap kali hashCode () dipanggil.

Yang penting ialah contoh String tidak dapat diubah: anda tidak boleh mendapatkan atau mengubah array char [] yang mendasari . Ciri rentetan lain ialah rentetan pemalar statik dimuat dan disimpan dalam kumpulan tali. Sekiranya anda mempunyai banyak objek String yang sama dalam kod sumber anda, semuanya ditunjukkan oleh satu contoh pada waktu runtime.

S15. Apa itu Stringbuilder dan Apakah Kes Penggunaannya? Apakah Perbezaan Antara Menambahkan String ke Stringbuilder dan Memadankan Dua String dengan Operator +? Bagaimana Stringbuilder Berbeza dengan Stringbuffer?

StringBuilder membolehkan memanipulasi urutan watak dengan menambahkan, menghapus dan memasukkan watak dan rentetan. Ini adalah struktur data yang dapat diubah , berbanding dengan kelas String yang tidak berubah.

Semasa menggabungkan dua contoh String , objek baru dibuat, dan rentetan disalin. Ini boleh membawa pengumpul sampah yang besar jika kita perlu membuat atau mengubah rentetan dalam satu gelung. StringBuilder membolehkan menangani manipulasi rentetan dengan lebih berkesan.

StringBuffer berbeza dari StringBuilder kerana ia selamat di dalam benang. Sekiranya anda perlu memanipulasi rentetan dalam satu utas, gunakan StringBuilder sebagai gantinya.

3. Kesimpulannya

Dalam artikel ini, kami telah membahas beberapa pertanyaan yang paling umum yang sering muncul dalam wawancara jurutera Java. Soalan mengenai pengurusan memori biasanya diajukan untuk calon Senior Java Developer kerana penemuduga menjangkakan bahawa anda telah membuat aplikasi yang tidak sepele yang sering kali dilanda masalah memori.

Ini tidak boleh dianggap sebagai daftar pertanyaan yang lengkap, melainkan sebagai landasan untuk penyelidikan lebih lanjut. Kami, di Baeldung, mengucapkan kejayaan dalam temu ramah yang akan datang.

Seterusnya » Soalan Temuduga Generik Java (+ Jawapan) « Soalan Temuduga Java 8 Sebelumnya (+ Jawapan)