日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

《深入理解 Java 虚拟机》把这个知识点讲错了?

發布時間:2025/3/15 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《深入理解 Java 虚拟机》把这个知识点讲错了? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

△Hollis, 一個對Coding有著獨特追求的人△

這是Hollis的第?380?篇原創分享

作者 l Hollis

來源 l Hollis(ID:hollischuang)

在之前的一篇文章中,介紹過Java中的Class常量池,在Java體系中,提到常量池,除了 Class常量池,還有運行時常量池和字符串常量池等概念。

很多人搞不清楚他們的區別與聯系,甚至還有人曾經有人對周志明老師的《深入理解 Java虛擬機》中關于這他們之間的關系的表述產生過質疑,詳見后文。

那么,到底什么是運行時常量池。他和字符串池之間的關系和區別又是什么呢?

Java虛擬機為每一個類型都維護了一個常量池,是 Java 虛擬機中的運行時數據結構,這里面主要存放的是編譯期生成的各種字面量和符號引用,這就是運行時常量池。

根據Java虛擬機規范約定:每一個運行時常量池都在Java虛擬機的方法區中分配,在加載類和接口到虛擬機后,就創建對應的運行時常量池。

規范中規定了運行時常量池屬于方法區,但是沒規定方法區屬于哪。于是虛擬機在各自實現的時候就各顯神通了。

JDK各個版本中的實現

在不同版本的JDK中,運行時常量池所處的位置也不一樣。以HotSpot虛擬機為例:

在JDK 1.7之前,方法區位于永久代,運行時常量池作為方法區的一部分,也處于永久代中。

因為使用永久代實現方法區可能導致內存泄露問題,所以,從JDK1.7開始,JVM嘗試解決這一問題。

在JDK 1.7中,靜態變量和運行時常量池中的字符串常量池轉移到了堆內存中,其他類型的變量還保留在方法區中。

在JDK 1.8中,徹底移除了永久代,方法區通過元空間的方式實現。隨之,運行時常量池也在元空間中實現。

池中常量的來源

運行時常量池中包含了若干種不同的常量,他的來源主要有兩種:

編譯期可知的字面量和符號引用(來自Class常量池)

運行期解析后可獲得的常量(如String的intern方法)

三種池之間的關系

虛擬機啟動過程中,會將各個Class文件中的常量池載入到運行時常量池中。

所以, Class常量池只是一個媒介場所。在JVM真的運行時,需要把常量池中的常量加載到內存中,進入到運行時常量池。這就是Class 常量池和運行時常量池之間的關系。

那么,字符串池(string literal pool)和運行時常量池(runtime constant pool)之間的關系和區別是什么呢?

關于這個問題,很多人都有疑問。很少有人能說清楚到底這兩者之間有啥具體的區別和聯系。

之前,就有人對周志明老師的《深入理解 Java虛擬機》中關于這二者之間的關系的表述產生過質疑,于是兩個人各自舉證,唇槍舌戰的辯論了很久(圍觀地址:https://github.com/fenixsoft/jvm_book/issues/112 )。

其實,這個事兒說來也簡單,主要是要區分「Java虛擬機規范」和「Java虛擬機實現」

首先,在官方的「Java虛擬機規范」中,明確的表示過,字符串字面量以及 intern 過的字符串內容,都是要進到運行時常量池的。

規范是這么說的,所以,不管咋說,字符串常量就是要存儲在運行時常量池的。

但是,具體的虛擬機實現的時候,可能有些自己的想法,如 HotSpot就給字符串常量池專門搞了個池用來存儲字符串常量。

而有人認為這兩個不是一回事的主要原因,其實,"罪魁禍首"也是HotSpot。

「Java虛擬機規范」規定運行時常量池要放到方法區,但是沒規定方法區要具體在哪實現。

如前文說過,JDK 1.8中,徹底移除了永久代,方法區通過元空間的方式實現。運行時常量池隨著去到了元空間中。

但是!字符串池還保留在堆內存中。

這就使得很多人認為,運行時常量池和字符串常量池好像沒啥關系,所在的位置都不一樣。

但是其實,不管 HotSpot 具體如何實現的,其實還是遵守「Java虛擬機規范」的,雖然在 JDK 1.8中,運行時常量池和字符串池不在同一個物理區域,但是這也不能說明字符串池不屬于運行時常量池。

或者說,字符串池就是運行時常量池的一個邏輯子區域。及字符串池是運行時常量池的分池!

所以,總結一下,Class 常量池的內容,會在編譯過后在運行期進入到運行時常量池,其中字符串的部分直接進到字符串池,其他常量進入到運行時常量池。至于在運行期,如果有對字符串進行過 intern 操作,那么也可能會在運行時動態向字符串池中添加新的字符串常量!

PS:本文節選自我已經寫完但是還未出版的新書,敬請期待。

技術交流群

最近有很多人問,有沒有讀者交流群,想知道怎么加入。

最近我創建了一些群,大家可以加入。交流群都是免費的,只需要大家加入之后不要隨便發廣告,多多交流技術就好了。

目前創建了多個交流群,全國交流群、北上廣杭深等各地區交流群、面試交流群、資源共享群等。

有興趣入群的同學,可長按掃描下方二維碼,一定要備注:全國 Or 城市 Or 面試 Or 資源,根據格式備注,可更快被通過且邀請進群。

▲長按掃描

往期推薦

突發!Log4j 爆“核彈級”漏洞,Flink、Kafka等至少十多個項目受影響


一個員工的離職成本有多恐怖!


快手裁員30%,大部分年薪超100w?工資越高越容易被裁,你慌了嗎?

如果你喜歡本文,

請長按二維碼,關注?Hollis.

轉發至朋友圈,是對我最大的支持。

點個?在看?

喜歡是一種感覺

在看是一種支持

↘↘↘

總結

以上是生活随笔為你收集整理的《深入理解 Java 虚拟机》把这个知识点讲错了?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。