Apakah ada cara untuk membebaskan memori di Jawa, mirip dengan free()
fungsi C ? Atau apakah mengatur objek ke nol dan mengandalkan GC satu-satunya opsi?
java
garbage-collection
Felix
sumber
sumber
Jawaban:
Java menggunakan memori yang dikelola, jadi satu-satunya cara Anda dapat mengalokasikan memori adalah dengan menggunakan
new
operator, dan satu-satunya cara Anda dapat mengalokasikan memori adalah dengan mengandalkan pengumpul sampah.Whitepaper manajemen memori ini (PDF) dapat membantu menjelaskan apa yang terjadi.
Anda juga dapat menelepon
System.gc()
untuk menyarankan agar pengumpul sampah segera beroperasi. Namun, Java Runtime membuat keputusan akhir, bukan kode Anda.Menurut dokumentasi Java ,
sumber
System.gc()
sepenuhnya.Tidak ada yang tampaknya telah menyebutkan secara eksplisit mengatur referensi objek
null
, yang merupakan teknik yang sah untuk "membebaskan" memori yang mungkin ingin Anda pertimbangkan.Misalnya, Anda menyatakan bahwa
List<String>
pada awal metode yang tumbuh menjadi sangat besar, tetapi hanya diperlukan hingga separuh jalan melalui metode. Anda bisa pada titik ini mengatur referensi Daftarnull
untuk memungkinkan pengumpul sampah untuk berpotensi mengklaim kembali objek ini sebelum metode selesai (dan referensi itu jatuh dari ruang lingkup tetap).Perhatikan bahwa saya jarang menggunakan teknik ini dalam kenyataan tetapi perlu dipertimbangkan ketika berhadapan dengan struktur data yang sangat besar.
sumber
Tidak direkomendasikan.
Sunting: Saya menulis respons asli pada 2009. Sekarang 2015.
Pengumpul sampah semakin membaik dalam ~ 20 tahun di Jawa. Pada titik ini, jika Anda secara manual memanggil pengumpul sampah, Anda mungkin ingin mempertimbangkan pendekatan lain:
sumber
* "Saya pribadi mengandalkan variabel nulling sebagai pengganti untuk penghapusan yang tepat di masa depan. Misalnya, saya meluangkan waktu untuk membatalkan semua elemen array sebelum benar-benar menghapus (membuat null) array itu sendiri."
Ini tidak perlu. Cara kerja Java GC adalah ia menemukan objek yang tidak memiliki referensi padanya, jadi jika saya memiliki Obyek x dengan referensi (= variabel) a yang menunjuk padanya, GC tidak akan menghapusnya, karena ada referensi ke objek itu:
Jika Anda batal dari ini terjadi:
Jadi sekarang x tidak memiliki referensi yang menunjuk ke sana dan akan dihapus. Hal yang sama terjadi ketika Anda mengatur referensi ke objek yang berbeda dari x.
Jadi jika Anda memiliki array array yang merujuk ke objek x, y dan z dan variabel a yang merujuk ke array, tampilannya seperti itu:
Jika Anda batal dari ini terjadi:
Jadi GC menemukan arr tidak memiliki referensi yang ditetapkan dan menghapusnya, yang memberi Anda struktur ini:
Sekarang GC menemukan x, y dan z dan menghapusnya juga. Menghapus setiap referensi dalam array tidak akan membuat sesuatu yang lebih baik, itu hanya akan menggunakan waktu dan ruang CPU dalam kode (yang mengatakan, tidak akan ada salahnya lebih jauh dari itu. GC masih akan dapat melakukan cara yang seharusnya ).
sumber
Alasan yang sah untuk ingin membebaskan memori dari program apa pun (java atau tidak) adalah untuk membuat lebih banyak memori tersedia untuk program lain pada tingkat sistem operasi. Jika aplikasi java saya menggunakan 250MB saya mungkin ingin memaksanya turun ke 1MB dan membuat 249MB tersedia untuk aplikasi lain.
sumber
Untuk memperluas jawaban dan komentar oleh Yiannis Xanthopoulos dan Hot Licks (maaf, saya belum bisa berkomentar!), Anda dapat mengatur opsi VM seperti contoh ini:
Dalam jdk 7 saya ini kemudian akan melepaskan memori VM yang tidak digunakan jika lebih dari 30% dari tumpukan menjadi bebas setelah GC ketika VM idle. Anda mungkin perlu menyetel parameter ini.
Walaupun saya tidak melihatnya ditekankan pada tautan di bawah, perhatikan bahwa beberapa pemulung mungkin tidak mematuhi parameter ini dan secara default java dapat memilih salah satu dari ini untuk Anda, seandainya Anda memiliki lebih dari satu inti (maka argumen UseG1GC di atas ).
Argumen VM
Pembaruan: Untuk java 1.8.0_73 Saya telah melihat JVM sesekali melepaskan jumlah kecil dengan pengaturan default. Tampaknya hanya melakukannya jika ~ 70% dari heap tidak digunakan .. tidak tahu apakah akan lebih agresif melepaskan jika OS pada memori fisik rendah.
sumber
Saya sudah melakukan eksperimen tentang ini.
Memang benar bahwa
System.gc();
hanya menyarankan untuk menjalankan Pengumpul Sampah.Tetapi memanggil
System.gc();
setelah mengatur semua referensinull
, akan meningkatkan kinerja dan pekerjaan memori.sumber
Jika Anda benar-benar ingin mengalokasikan dan membebaskan blok memori, Anda dapat melakukan ini dengan ByteBuffers langsung. Bahkan ada cara non-portabel untuk membebaskan memori.
Namun, seperti yang telah disarankan, hanya karena Anda harus membebaskan memori dalam C, bukan berarti itu ide yang baik untuk melakukan ini.
Jika Anda merasa memiliki kasus penggunaan yang baik gratis (), harap sertakan dalam pertanyaan sehingga kami dapat melihat apa yang ingin Anda lakukan, kemungkinan besar ada cara yang lebih baik.
sumber
Seluruhnya dari javacoffeebreak.com/faq/faq0012.html
sumber
Dalam kasus saya, karena kode Java saya dimaksudkan untuk porting ke bahasa lain dalam waktu dekat (Terutama C ++), saya setidaknya ingin membayar layanan bibir untuk mengosongkan memori dengan benar sehingga membantu proses porting nanti.
Saya pribadi mengandalkan variabel nulling sebagai pengganti untuk penghapusan yang tepat di masa depan. Sebagai contoh, saya meluangkan waktu untuk membatalkan semua elemen array sebelum benar-benar menghapus (membuat null) array itu sendiri.
Tapi kasus saya sangat khusus, dan saya tahu saya mendapat pukulan kinerja saat melakukan ini.
sumber
* "Misalnya, katakan Anda akan mendeklarasikan Daftar di awal metode yang ukurannya menjadi sangat besar, tetapi hanya diperlukan hingga separuh jalan melalui metode. Anda bisa pada titik ini menetapkan referensi Daftar ke nol untuk memungkinkan pemungut sampah untuk berpotensi mengklaim kembali objek ini sebelum metode selesai (dan referensi tetap berada di luar jangkauan). " *
Ini benar, tetapi solusi ini mungkin tidak dapat digeneralisasikan. Saat mengatur referensi objek Daftar ke null-akan- membuat memori tersedia untuk pengumpulan sampah, ini hanya berlaku untuk objek Daftar tipe primitif. Jika objek Daftar bukan berisi tipe referensi, pengaturan objek List = null tidak akan dereference -any- dari tipe referensi yang terkandung -in- daftar. Dalam kasus ini, mengatur Daftar objek = null akan menjadi yatim jenis referensi yang terkandung yang objeknya tidak akan tersedia untuk pengumpulan sampah kecuali algoritma pengumpulan sampah cukup pintar untuk menentukan bahwa objek telah yatim piatu.
sumber
Algress java menyediakan pengumpulan sampah otomatis kadang-kadang Anda ingin tahu seberapa besar objek itu dan berapa banyak yang tersisa. Memori bebas menggunakan secara terprogram
import java.lang;
danRuntime r=Runtime.getRuntime();
untuk mendapatkan nilai memori yang digunakanmem1=r.freeMemory();
untuk membebaskan memori, panggilr.gc();
metode dan panggilanfreeMemory()
sumber
Rekomendasi dari JAVA adalah menetapkan untuk null
Dari https://docs.oracle.com/cd/E19159-01/819-3681/abebi/index.html
sumber