String menempati sejumlah besar memori dalam aplikasi apa pun. Secara khusus, array char [] yang berisi karakter UTF-16 independen berkontribusi paling besar untuk konsumsi memori JVM--karena setiap karakter menempati 2 digit.
30%dari memori sebenarnya sangat umum. Menggunakan Java 8 Update 20, kita sekarang dapat menghubungi fitur baru, yang disebut string untuk menjadi berat.
String ini digunakan kembali untuk menggunakan kembali internal string sebenarnya adalah array char dan fitur final, sehingga JVM dapat memanipulasinya secara sewenang -wenang.
Pengembang mempertimbangkan banyak strategi untuk string string, tetapi implementasi akhir digunakan dalam implementasi akhir:
Setiap kali perangkat pemulihan sampah mengakses objek string, itu akan menandai array char. Itu memperoleh nilai hash dari array char dan ada dengan referensi yang lemah ke array. Selama pendaur ulang sampah menemukan string lain, dan string ini dan array char memiliki kode hash yang sama, maka keduanya dibandingkan dengan satu karakter dan satu karakter.
Jika mereka cocok, string akan dimodifikasi, menunjuk ke array char dari string kedua. Array Char pertama tidak lagi dikutip, sehingga dapat didaur ulang.
Tentu saja, seluruh proses ini membawa beberapa pengeluaran, tetapi dikendalikan oleh batas atas yang sangat ketat. Misalnya, jika suatu karakter tidak ditemukan diulang, itu tidak akan lagi diperiksa untuk jangka waktu tertentu.
Jadi bagaimana cara kerja fitur ini? Pertama -tama, Anda hanya perlu merilis Java 8 Update 20, dan kemudian ikuti konfigurasi ini: -xmx256m -xx:+USEG1GC untuk menjalankan kode berikut:
Kelas Publik Lotofstrings {Private Static Final LinkedList <String> lot_of_strings = new LinkedList <() (); J = 0; );}}}
Kode ini akan dilaporkan ke OutofMemoryError setelah 30 iterasi.
Sekarang, buka string untuk menjadi berat, gunakan konfigurasi berikut untuk menjalankan kode di atas:
-Xmx256m -xx:+useG1gc -xx:+Usestringdedupplication -xx:+printStringLicationStator
Pada saat ini, itu bisa berjalan lebih lama, dan hanya akan berakhir setelah 50 iterasi.
JVM juga mencetak apa yang telah dilakukan, mari kita lihat:
[GC-Deduplikasi-Concurrent-String, 4658.2k-> 0,0b (4658.2k), rata-rata 99,6%, 0,0165023 detik] [EXEC Last: 0,0165023 detik, idle: 0,0953764 detik: Diblokir: 0/0,0000.000 Secs] [0,0953764]: Detik: 0/0,0000.000 Secs: 0,09537. [Detik]: 0/0.0000000] [INSPEK: 0/0.0000000] [INSPEK: 0/0.0000.000: [Skippd: 0 (0,0%)] [Hashed: 119538 (100,0%)] [Diketahui: 0 (0,0%)] [Baru: 119538 (100,0%) 4658,2k] [Deduplikasi: 119538 (100,0%) 4658.2k (100.0 .0.0] [Young: 372 (0,3%) 14,5k (0,3%)] [Lama: 119166 (99,7%) 4643,8k (99,7%)] [Total Exec: 4/0,0802259 detik, idle: 4/0,6491928 SECS, diblokir : 0/0.0000000 detik] [Diinspeksi: 557503] [dilewati: 0 (0,0%)] [Hashed: 556191 (99,8%)] [diketahui: 903 (0,2%)] [Baru: 556600 (99,8%) 21,2m] [ Diduplikasi: 554727 (99,7%) 21,1m (99,6%)] [Young: 1101 (0,2%) 43,0k (0,2%)] [Lama: 553626 (99,8%) 21,1m (99,8%)] [Tabel] [Penggunaan Memori Memori : 81.1k] [Ukuran: 2048, min: 1024, maks: 16777216] [Entri: 2776, beban: 135,5%, di -cache: 0, Ditambahkan: 2776, Dihapus: 0] [Ubah Ukuran: 1, Kecilkan Threeold: 13 65 (65 (66,7%), Grow Threshold: 4096 (200,0%)] [Jumlah Rehash: 0, Rehash Threshold: 120, Hash Seed: 0x0] [Ambang Umur: 3] [Antrian] [DROPPED: 0]
Untuk kenyamanan, kita tidak perlu menghitung penambahan semua data sendiri, dan itu cukup untuk menggunakannya dengan mudah.
Segmen kode di atas menetapkan bahwa string tercapai berat.
Fitur -fitur di atas baru saja diluncurkan, yang berarti bahwa itu mungkin tidak ditinjau secara komprehensif.具体的数据在实际的应用中可能看起来有差别 , 尤其是那些应用中字符串被多次使用和传递 , 因此一些字符串可能被跳过或者早就有了 HashCode (正如你可能知道的那样 , Kode hash string dimuat dengan malas).
Dalam kasus di atas, semua string berat, dan 4.5MB data dihapus dalam memori.
[Tabel] Bagian dari informasi statistik tentang tabel pelacakan internal diberikan.
Jadi, apa perbedaan antara bobot string dan tempat tinggal string? Bahkan, string tergantung padanya mirip dengan tempat tinggal.
Kontroversi pencipta Proposal Peningkatan JDK 192 adalah bahwa pengembang sering tidak tahu di mana harus meletakkan string penduduk yang sesuai, atau disembunyikan oleh kerangka kerja. dari negara), Anda membutuhkan akal sehat.
Ketika string tetap di utas aplikasi, ketika pemulihan sampah asinkron dan ditransmisikan, string tidak akan meningkatkan konsumsi selama runtime. Ini akan menambah banyak tekanan pada GC, sehingga string tidak akan terjadi sama sekali.