Pool konstan string di java
Ada dua bentuk pembuatan objek string di Java. Salah satunya adalah bentuk literal, seperti string str = "droid"; dan yang lainnya adalah metode standar untuk membangun objek menggunakan yang baru, seperti string str = string baru ("droid");. Kami sering menggunakan dua metode ini saat menulis kode, terutama metode literal. Namun, kedua implementasi ini sebenarnya memiliki beberapa perbedaan dalam penggunaan kinerja dan memori. Semua ini disebabkan oleh fakta bahwa JVM mempertahankan memori khusus untuk mengurangi pembuatan objek string yang berulang, yang merupakan kumpulan string konstan atau kumpulan literal string.
Cara kerjanya
Ketika objek string dibuat dalam bentuk literal dalam kode, JVM pertama -tama akan memeriksa literal. Jika ada referensi ke objek string dengan konten yang sama di kumpulan string konstanta, referensi akan dikembalikan. Kalau tidak, objek string baru akan dibuat, dan kemudian referensi akan ditempatkan ke kumpulan string konstan dan referensi akan dikembalikan.
Berikan contoh
Bentuk penciptaan literal
String str1 = "droid";
JVM mendeteksi literal ini, di sini kami berpikir bahwa tidak ada objek dengan konten yang ada droid. JVM tidak dapat menemukan objek string dengan konten droid melalui kumpulan string konstanta, sehingga akan membuat objek string ini, dan kemudian memasukkan referensi objek yang baru saja Anda buat ke dalam kumpulan string konstanta, dan mengembalikan referensi ke variabel STR1.
Jika ada kode seperti ini berikutnya
String str2 = "droid";
Demikian pula, JVM masih perlu mendeteksi literal ini. Dengan mencari kumpulan string konstanta, JVM menemukan bahwa konten adalah objek string "droid", sehingga mengembalikan referensi objek string yang ada ke variabel STR2. Perhatikan bahwa objek string baru tidak akan diciptakan kembali di sini.
Verifikasi apakah STR1 dan STR2 menunjuk ke objek yang sama, kita dapat menggunakan kode ini
System.out.println (str1 == str2);
Hasilnya benar.
Buat dengan yang baru
String str3 = string baru ("droid");
Ketika kami menggunakan baru untuk membuat objek string, objek string baru akan dibuat terlepas dari apakah ada referensi ke objek dengan konten yang sama di kumpulan string konstanta. Jadi mari kita gunakan kode berikut untuk mengujinya.
String str3 = string baru ("droid");
System.out.println (str1 == str3);
Hasilnya salah seperti yang kita pikirkan, menunjukkan bahwa dua variabel menunjuk ke objek yang berbeda.
magang
Untuk objek string yang dibuat dengan yang baru di atas, jika Anda ingin menambahkan referensi ke kumpulan string konstanta, Anda dapat menggunakan metode magang.
Setelah menelepon magang, pertama -tama periksa apakah ada referensi ke objek di kumpulan string konstan. Jika ada, kembalikan referensi ini ke variabel, jika tidak referensi akan ditambahkan dan dikembalikan ke variabel.
String str4 = str3.intern ();
System.out.println (str4 == str1);
Hasil output benar.
Masalah sulit
Prasyarat?
Prasyarat untuk menerapkan kumpulan string konstan adalah bahwa objek string di Java tidak dapat diubah, yang dapat dengan aman memastikan bahwa beberapa variabel berbagi objek yang sama. Jika objek string di Java adalah variabel, dan satu operasi referensi mengubah nilai objek, variabel lain juga akan terpengaruh, jelas ini tidak masuk akal.
Referensi atau objek
Pertanyaan ini paling umum ketika kumpulan string konstan disimpan dalam referensi atau objek. String Constant Pool menyimpan referensi objek, bukan objek. Di Java, objek dibuat dalam memori tumpukan.
Verifikasi pembaruan, banyak komentar yang diterima juga membahas masalah ini, dan saya cukup memverifikasi. Verifikasi lingkungan
22: 18: 54-androidyue ~/video $ Cat/etc/os-releasename = fedoraversion = "17 (Beefy Miracle)" id = fedoraversion_id = 17pretty_name = "Fedora 17 (Beefy Miracle) "ANSI_COLOR =" 0; 34 "CPE_NAME =" CPE:/O: Fedoraproject: Fedora: 17 "22: 19: 04-Androidyue ~/Video $ Java -Versionjava Versi 64-BIT6.17.17" Lingkungan Runtime OpenJDK (Fedora-2.3.12.12.12.17. VM (Build 23.7-B01, Mode Campuran)
Ide Verifikasi: Program Java berikut membaca file video dengan ukuran 82m dan melakukan operasi magang dalam bentuk string.
22: 01: 17 -androidyue ~/video $ ll -lh | grep why_to_learn.mp4-rw-rw-r--. 1 androidyue androidyue 82m 20 Okt 2013 Why_to_learn.mp4
Kode verifikasi
impor java.io.bufferedReader; impor java.io.filenotfoundException; impor java.io.filereader; impor java.io.ioException; testmain kelas publik {private static string filecontent; public static void main (string [] args) {filecontent = readFileToString (args [0]); if (null! = filecontent) {filecontent = filecontent.intern (); System.out.println ("not null"); }} private static string readFileToString (file string) {buferedReader reader = null; coba {reader = new bufferedReader (filereader baru (file)); StringBuffer buff = new StringBuffer (); Garis string; while ((line = reader.readline ())! = null) {buff.append (line); } return buff.toString (); } catch (FileNotFoundException e) {e.printstacktrace (); } catch (ioException e) {e.printstacktrace (); } akhirnya {if (null! = reader) {coba {reader.close (); } catch (ioException e) {e.printstacktrace (); }}} return null; }}Karena kumpulan string konstan ada dalam generasi permanen dalam memori heap, itu cocok sebelum Java 8. Kami memverifikasi dengan menetapkan generasi permanen dari nilai kecil. Jika objek string ada di kumpulan string konstanta, kesalahan ruang permgen java.lang.outofmemoryError harus dilemparkan.
java -xx: permsize = 6m testmain ~/video/why_to_learn.mp4
Menjalankan Program Bukti tidak melempar OOM, tetapi ini tidak dapat membuktikan bahwa itu disimpan sebagai objek atau referensi.
Tetapi setidaknya ini membuktikan bahwa char objek konten aktual [] dari string tidak disimpan dalam kumpulan konstanta string. Dalam hal ini, tidak penting bahwa string konstanta pool menyimpan referensi ke objek string atau objek string. Tetapi individu masih cenderung menyimpan referensi.
Pro dan kontra
Keuntungan dari gabungan konstan string adalah untuk mengurangi pembuatan string dari konten yang sama dan menghemat ruang memori.
Jika Anda harus mengatakan kerugiannya, itu adalah untuk mengorbankan waktu komputasi CPU untuk bertukar ruang. Waktu perhitungan CPU terutama digunakan untuk menemukan apakah ada referensi ke objek dengan konten yang sama di kumpulan konstanta string. Namun, implementasinya hashtable, sehingga biaya perhitungannya rendah.
Daur Ulang GC?
Karena kumpulan string konstanta memegang referensi ke objek string bersama, apakah ini berarti bahwa objek ini tidak dapat didaur ulang?
Pertama -tama, objek bersama dalam pertanyaan umumnya lebih kecil. Sejauh yang saya verifikasi, memang ada masalah seperti itu dalam versi sebelumnya, tetapi dengan pengenalan referensi yang lemah, masalah ini harus hilang saat ini.
Mengenai masalah ini, Anda dapat mempelajari lebih lanjut tentang artikel ini. String yang Diinternir: Glosari Java
Gunakan magang?
Prasyarat untuk menggunakan magang adalah Anda tahu bahwa Anda benar -benar perlu menggunakannya. Misalnya, kami memiliki catatan jutaan orang di sini, di mana nilai catatan tertentu adalah California, USA berkali -kali. Kami tidak ingin membuat jutaan objek string tersebut. Kami dapat menggunakan magang untuk menyimpan hanya satu salinan di memori. Untuk pemahaman magang yang lebih mendalam, silakan merujuk ke analisis mendalam dari String#Intern.
Apakah selalu ada pengecualian?
Apakah Anda tahu kode berikut akan membuat beberapa objek string dan menyimpan beberapa referensi dalam kumpulan string konstanta?
String test = "a" + "b" + "c";
Jawabannya adalah bahwa hanya satu objek yang dibuat dan hanya satu referensi yang disimpan di kumpulan konstan. Kami menggunakan dekompilasi Javap dan melihatnya.
17:02 $ javap -c testinternedpoolgccompiled dari "testinternedpoolgc.java" testinternedpoolgc kelas publik meluas java.lang.Object {public testInternedPoolGC (); Kode: 0: aload_0 1: Invokespecial #1; // metode java/lang/objek. "<inin>" :() v 4: returnPublic static void main (java.lang.string []) melempar java.lang.exception; Kode: 0: LDC #2; // String ABC 2: Store_1 3: ReturnPernahkah Anda melihatnya? Bahkan, selama periode kompilasi, ketiga literal ini telah disintesis menjadi satu. Ini sebenarnya adalah optimasi yang menghindari membuat objek string yang berlebihan dan tidak memiliki masalah jahitan string. Untuk jahitan string, Anda dapat melihat detail java: jahitan string.
Di atas adalah kompilasi informasi tentang kumpulan string konstan di java. Kami akan terus menambahkan informasi yang relevan di masa mendatang. Terima kasih atas dukungan Anda untuk situs ini!