国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Rumah Java JavaAsas java常量池圖文詳解

java常量池圖文詳解

Nov 30, 2019 pm 04:36 PM
java

java常量池圖文詳解

java常量池是一個經(jīng)久不衰的話題,也是面試官的最愛,題目花樣百出,小菜早就對常量池有所耳聞,這次好好總結一下。

推薦:java視頻教程

jvm虛擬內存分布:

1.jpg

程序計數(shù)器是jvm執(zhí)行程序的流水線,存放一些跳轉指令,這個太高深,小菜不懂。

本地方法棧是jvm調用操作系統(tǒng)方法所使用的棧。

虛擬機棧是jvm執(zhí)行java代碼所使用的棧。

方法區(qū)存放了一些常量、靜態(tài)變量、類信息等,可以理解成class文件在內存中的存放位置。

虛擬機堆是jvm執(zhí)行java代碼所使用的堆。

Java中的常量池,實際上分為兩種形態(tài):靜態(tài)常量池和運行時常量池。

所謂靜態(tài)常量池,即*.class文件中的常量池,class文件中的常量池不僅僅包含字符串(數(shù)字)字面量,還包含類、方法的信息,占用class文件絕大部分空間。

?而運行時常量池,則是jvm虛擬機在完成類裝載操作后,將class文件中的常量池載入到內存中,并保存在方法區(qū)中,我們常說的常量池,就是指方法區(qū)中的運行時常量池。

接下來我們引用一些網(wǎng)絡上流行的常量池例子,然后借以講解。

String s1 = "Hello";
String s2 = "Hello";
String s3 = "Hel" + "lo";
String s4 = "Hel" + new String("lo");
String s5 = new String("Hello");
String s6 = s5.intern();
String s7 = "H";
String s8 = "ello";
String s9 = s7 + s8;
          
System.out.println(s1 == s2);  // true
System.out.println(s1 == s3);  // true
System.out.println(s1 == s4);  // false
System.out.println(s1 == s9);  // false
System.out.println(s4 == s5);  // false
System.out.println(s1 == s6);  // true

首先說明一點,在java 中,直接使用==操作符,比較的是兩個字符串的引用地址,并不是比較內容,比較內容請用String.equals()。

s1 == s2這個非常好理解,s1、s2在賦值時,均使用的字符串字面量,說白話點,就是直接把字符串寫死,在編譯期間,這種字面量會直接放入class文件的常量池中,從而實現(xiàn)復用,載入運行時常量池后,s1、s2指向的是同一個內存地址,所以相等。

s1 == s3這個地方有個坑,s3雖然是動態(tài)拼接出來的字符串,但是所有參與拼接的部分都是已知的字面量,在編譯期間,這種拼接會被優(yōu)化,編譯器直接幫你拼好,因此String s3 = "Hel" + "lo";在class文件中被優(yōu)化成String s3 = "Hello";,所以s1 == s3成立。

s1 == s4當然不相等,s4雖然也是拼接出來的,但new String("lo")這部分不是已知字面量,是一個不可預料的部分,編譯器不會優(yōu)化,必須等到運行時才可以確定結果,結合字符串不變定理,鬼知道s4被分配到哪去了,所以地址肯定不同。配上一張簡圖理清思路:

2.jpgs1 == s9也不相等,道理差不多,雖然s7、s8在賦值的時候使用的字符串字面量,但是拼接成s9的時候,s7、s8作為兩個變量,都是不可預料的,編譯器畢竟是編譯器,不可能當解釋器用,所以不做優(yōu)化,等到運行時,s7、s8拼接成的新字符串,在堆中地址不確定,不可能與方法區(qū)常量池中的s1地址相同。

3.jpg

s4 == s5已經(jīng)不用解釋了,絕對不相等,二者都在堆中,但地址不同。

s1 == s6這兩個相等完全歸功于intern方法,s5在堆中,內容為Hello ,intern方法會嘗試將Hello字符串添加到常量池中,并返回其在常量池中的地址,因為常量池中已經(jīng)有了Hello字符串,所以intern方法直接返回地址;而s1在編譯期就已經(jīng)指向常量池了,因此s1和s6指向同一地址,相等。

至此,我們可以得出三個非常重要的結論:

必須要關注編譯期的行為,才能更好的理解常量池。

運行時常量池中的常量,基本來源于各個class文件中的常量池。

程序運行時,除非手動向常量池中添加常量(比如調用intern方法),否則jvm不會自動添加常量到常量池。

以上所講僅涉及字符串常量池,實際上還有整型常量池、浮點型常量池等等,但都大同小異,只不過數(shù)值類型的常量池不可以手動添加常量,程序啟動時常量池中的常量就已經(jīng)確定了,比如整型常量池中的常量范圍:-128~127,只有這個范圍的數(shù)字可以用到常量池。

實踐

說了這么多理論,接下來讓我們觸摸一下真正的常量池。

前文提到過,class文件中存在一個靜態(tài)常量池,這個常量池是由編譯器生成的,用來存儲java源文件中的字面量(本文僅僅關注字面量),假設我們有如下java代碼:

 String s = "hi";

為了方便起見,就這么簡單,沒錯!將代碼編譯成class文件后,用winhex打開二進制格式的class文件。如圖:

5.jpg

簡單講解一下class文件的結構,開頭的4個字節(jié)是class文件魔數(shù),用來標識這是一個class文件,說白話點就是文件頭,既:CA FE BA BE。

緊接著4個字節(jié)是java的版本號,這里的版本號是34,因為筆者是用jdk8編譯的,版本號的高低和jdk版本的高低相對應,高版本可以兼容低版本,但低版本無法執(zhí)行高版本。所以,如果哪天讀者想知道別人的class文件是用什么jdk版本編譯的,就可以看這4個字節(jié)。

接下來就是常量池入口,入口處用2個字節(jié)標識常量池常量數(shù)量,本例中數(shù)值為00 1A,翻譯成十進制是26,也就是有25個常量,其中第0個常量是特殊值,所以只有25個常量。

常量池中存放了各種類型的常量,他們都有自己的類型,并且都有自己的存儲規(guī)范,本文只關注字符串常量,字符串常量以01開頭(1個字節(jié)),接著用2個字節(jié)記錄字符串長度,然后就是字符串實際內容。本例中為:01 00 02 68 69。

接下來再說說運行時常量池,由于運行時常量池在方法區(qū)中,我們可以通過jvm參數(shù):-XX:PermSize、-XX:MaxPermSize來設置方法區(qū)大小,從而間接限制常量池大小。

假設jvm啟動參數(shù)為:-XX:PermSize=2M -XX:MaxPermSize=2M,然后運行如下代碼:

//保持引用,防止自動垃圾回收
List<String> list = new ArrayList<String>();
        
int i = 0;
        
while(true){
    //通過intern方法向常量池中手動添加常量
    list.add(String.valueOf(i++).intern());
}

程序立刻會拋出:Exception in thread "main" java.lang.outOfMemoryError: PermGen space異常。PermGen space正是方法區(qū),足以說明常量池在方法區(qū)中。

在jdk8中,移除了方法區(qū),轉而用Metaspace區(qū)域替代,所以我們需要使用新的jvm參數(shù):-XX:MaxMetaspaceSize=2M,依然運行如上代碼,拋出:java.lang.OutOfMemoryError: Metaspace異常。同理說明運行時常量池是劃分在Metaspace區(qū)域中。具體關于Metaspace區(qū)域的知識,請讀者自行搜索。

更多java知識請關注java基礎教程欄目。

Atas ialah kandungan terperinci java常量池圖文詳解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Tutorial PHP
1502
276
Bagaimana menangani transaksi di Java dengan JDBC? Bagaimana menangani transaksi di Java dengan JDBC? Aug 02, 2025 pm 12:29 PM

Untuk mengendalikan transaksi JDBC dengan betul, anda mesti terlebih dahulu mematikan mod komit automatik, kemudian melakukan pelbagai operasi, dan akhirnya melakukan atau mengembalikan semula hasilnya; 1. Panggil Conn.SetAutOcommit (palsu) untuk memulakan transaksi; 2. Melaksanakan pelbagai operasi SQL, seperti memasukkan dan mengemaskini; 3. Panggil Conn.Commit () jika semua operasi berjaya, dan hubungi conn.rollback () jika pengecualian berlaku untuk memastikan konsistensi data; Pada masa yang sama, cuba-dengan-sumber harus digunakan untuk menguruskan sumber, mengendalikan pengecualian dengan betul dan menutup sambungan untuk mengelakkan kebocoran sambungan; Di samping itu, adalah disyorkan untuk menggunakan kolam sambungan dan menetapkan mata simpan untuk mencapai rollback separa, dan menyimpan urus niaga sesingkat mungkin untuk meningkatkan prestasi.

Bagaimana untuk bekerja dengan kalendar di Jawa? Bagaimana untuk bekerja dengan kalendar di Jawa? Aug 02, 2025 am 02:38 AM

Gunakan kelas dalam pakej Java.Time untuk menggantikan kelas lama dan kelas kalendar; 2. Dapatkan tarikh dan masa semasa melalui LocalDate, LocalDateTime dan Tempatan Tempatan; 3. Buat tarikh dan masa tertentu menggunakan kaedah (); 4. Gunakan kaedah tambah/tolak untuk meningkatkan dan mengurangkan masa; 5. Gunakan zoneddatetime dan zonid untuk memproses zon waktu; 6. Format dan parse date string melalui DateTimeFormatter; 7. Gunakan segera untuk bersesuaian dengan jenis tarikh lama apabila perlu; pemprosesan tarikh di java moden harus memberi keutamaan untuk menggunakan java.timeapi, yang memberikan jelas, tidak berubah dan linear

Membandingkan kerangka Java: Spring Boot vs Quarkus vs Micronaut Membandingkan kerangka Java: Spring Boot vs Quarkus vs Micronaut Aug 04, 2025 pm 12:48 PM

Pra-formancetartuptimemoryusage, quarkusandmicronautleadduetocompile-timeprocessingandgraalvsupport, withquarkusoftenperforminglightbetterine serverless scenarios.tyvelopecosyste,

Memahami Pelabuhan Rangkaian dan Firewall Memahami Pelabuhan Rangkaian dan Firewall Aug 01, 2025 am 06:40 AM

NetworkPortsandFireWallSworkTogethertoenableCommunicationWileensuringsecurity.1.networkportsarevirtualendpointsNumbered0-655 35, Withwell-KnownportsLike80 (http), 443 (https), 22 (ssh), dan25 (smtp) identitispecificservices.2.portsoperateovertcp (boleh dipercayai, c

Bagaimana pengumpulan sampah berfungsi di java? Bagaimana pengumpulan sampah berfungsi di java? Aug 02, 2025 pm 01:55 PM

Koleksi Sampah Java (GC) adalah mekanisme yang secara automatik menguruskan ingatan, yang mengurangkan risiko kebocoran ingatan dengan menuntut semula objek yang tidak dapat dicapai. 1.GC menghakimi kebolehcapaian objek dari objek akar (seperti pembolehubah stack, benang aktif, medan statik, dan lain -lain), dan objek yang tidak dapat dicapai ditandakan sebagai sampah. 2. Berdasarkan algoritma penandaan tanda, tandakan semua objek yang dapat dicapai dan objek yang tidak ditandai. 3. Mengamalkan strategi pengumpulan generasi: Generasi Baru (Eden, S0, S1) sering melaksanakan MinorGC; Orang tua melakukan kurang tetapi mengambil masa lebih lama untuk melakukan MajorGC; Metaspace Stores Metadata kelas. 4. JVM menyediakan pelbagai peranti GC: SerialGC sesuai untuk aplikasi kecil; ParallelGC meningkatkan throughput; CMS mengurangkan

Menggunakan jenis html `input` untuk data pengguna Menggunakan jenis html `input` untuk data pengguna Aug 03, 2025 am 11:07 AM

Memilih jenis htmlinput yang betul dapat meningkatkan ketepatan data, meningkatkan pengalaman pengguna, dan meningkatkan kebolehgunaan. 1. Pilih jenis input yang sepadan mengikut jenis data, seperti teks, e -mel, tel, nombor dan tarikh, yang secara automatik boleh menyemak dan menyesuaikan diri dengan papan kekunci; 2. Gunakan HTML5 untuk menambah jenis baru seperti URL, Warna, Julat dan Carian, yang dapat memberikan kaedah interaksi yang lebih intuitif; 3. Gunakan pemegang tempat dan sifat -sifat yang diperlukan untuk meningkatkan kecekapan dan ketepatan pengisian bentuk, tetapi harus diperhatikan bahawa pemegang tempat tidak dapat menggantikan label.

Membandingkan Java Build Tools: Maven vs Gradle Membandingkan Java Build Tools: Maven vs Gradle Aug 03, 2025 pm 01:36 PM

GradleisthebetterChoiceFormostNewProjectSduetoitSsuperiorflexibility, Prestasi, danModernToolingSupport.1.Gradle'sGroovy/KOT lindslismoreconciseandexpressivethanmaven'sverbosexml.2.GradleOutPerformsMaveninBuildSpeedWithIncrementalcompilation, BuildCac

Pergi dengan contoh penangguhan yang dijelaskan Pergi dengan contoh penangguhan yang dijelaskan Aug 02, 2025 am 06:26 AM

Defer digunakan untuk melaksanakan operasi tertentu sebelum fungsi pulangan, seperti sumber pembersihan; Parameter dinilai dengan serta-merta apabila menangguhkan, dan fungsi-fungsi dilaksanakan mengikut urutan terakhir (LIFO); 1. Pelbagai penahanan dilaksanakan dalam urutan terbalik pengisytiharan; 2. Biasanya digunakan untuk pembersihan yang selamat seperti penutupan fail; 3. Nilai pulangan yang dinamakan boleh diubah suai; 4. Ia akan dilaksanakan walaupun panik berlaku, sesuai untuk pemulihan; 5. Elakkan penyalahgunaan menangguhkan gelung untuk mengelakkan kebocoran sumber; Penggunaan yang betul boleh meningkatkan keselamatan kod dan kebolehbacaan.

See all articles