程序計數(shù)器(Program Counter)
創(chuàng)新互聯(lián)公司是專業(yè)的石獅網(wǎng)站建設公司,石獅接單;提供成都網(wǎng)站制作、成都網(wǎng)站設計,網(wǎng)頁設計,網(wǎng)站設計,建網(wǎng)站,PHP網(wǎng)站建設等專業(yè)做網(wǎng)站服務;采用PHP框架,可快速的進行石獅網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!
程序計數(shù)器作為一個概念模型,這個是用來指示下一條需要執(zhí)行的字節(jié)碼指令在哪。
Java的多線程實際上是通過線程輪轉做到的,如果是一個單核的機器(或單cpu),嚴格意義上在一個時間塊中只會有一個線程在執(zhí)行。為了線程切換以后能恢復到正確的執(zhí)行位置,每個線程都需要有一個單獨的計數(shù)器,每個計數(shù)器之間要是獨立的互不干擾。
如果線程執(zhí)行的是Java方法,那么PC指向的是正在執(zhí)行的虛擬機字節(jié)碼指令的區(qū)域,如果執(zhí)行的是native方法,那么它是undefined。
Java虛擬機棧
Java virtue machine也是線程私有的,它擁有一個和線程相同的生命周期
虛擬機棧描述的是Java方法執(zhí)行的內(nèi)存模型;stack frame(棧幀)是一個經(jīng)常談及的概念,它用來儲存內(nèi)部變量表,操作數(shù)棧,動態(tài)鏈接,方法出口等等。
每一個方法從調(diào)用到執(zhí)行完畢,也就對應著一個棧幀在虛擬機棧中的入棧和出棧
我們以前畫圖來說明內(nèi)存區(qū)的時候,總是去關注Heap(堆內(nèi)存)和stack(棧內(nèi)存)這兩部分,這是與對象內(nèi)存分配最相關的兩塊內(nèi)存區(qū)。通常所說的stack就是虛擬機棧,或者更具體的說是虛擬機棧中的局部變量表。
局部變量表存放了編譯器可知的各種基本數(shù)據(jù)類型(boolean byte double char int short long float)對象引用(reference類型,并不是對象本身,可能是地址的引用指針,也可能是一個代代表對象的句柄)return address類型(指向一條字節(jié)碼指令的地址)
局部變量表的意義就在于,可以把表所需的內(nèi)存在編譯器就進行分配,每次程序去調(diào)用一個方法的時候,方法需要在frame中分配多少的局部內(nèi)存空間是確定的。
兩種異常情況
如果線程請求的棧的深度大于虛擬機所允許的,就是StackOverFlowError,如果是支持動態(tài)拓展的虛擬機(大部分的現(xiàn)代虛擬機都支持)依然無法申請到足夠的內(nèi)存,就會報出OutOfMemoryError異常。
本地方法棧
本地方法棧是和Java虛擬機棧對應的一個概念,它們的作用也是相近的,唯一的不同是,本地方法棧執(zhí)行的是native方法,而Java虛擬機棧執(zhí)行的是Java方法(也就是字節(jié)碼)服務
在Sun的HotSpot虛擬機里面,本地方法棧和虛擬機棧是一個。
Java堆
堆是被所有的線程所共享的一塊區(qū)域,這塊內(nèi)存區(qū)域存在的唯一目的就是存放對象實例,在虛擬機啟動的時候就會被創(chuàng)建,幾乎所有的對象實例都會在這里被分配內(nèi)存
所有的對象實例和數(shù)組都要在堆上分配 --《Java虛擬機規(guī)范》
隨著JIT編譯器的發(fā)展和逃逸技術的成熟,這句話也變得不是那么的絕對了。
GC(garbage collection)也發(fā)生在這個區(qū)域,所以有時候也被稱為GC堆
方法區(qū)
方法區(qū)和Java堆相似,是線程共享的一段內(nèi)存區(qū)域,它用于儲存已經(jīng)被虛擬機加載的類信息,常量,靜態(tài)變量,即時編譯器編譯后的代碼。
聽起來好像和Java堆很像,Java虛擬機標準里面也把它視為堆的一個邏輯部分,但是它被稱作Non-Heap,目的是和Java堆區(qū)分開來。
Permanent Generation?那么,這個方法區(qū)就是永久代嗎,并不是。只是在HotSpot虛擬機的設計中,用永久代來實現(xiàn)了方法區(qū)。(在JDK1.7中,已經(jīng)把原本放在永久代的字符串常量池移出了)
運行時常量池(Runtime Constant Pool)
這也是方法區(qū)的一個較重要的部分,.class文件除了有類的版本,字段,方法,接口等描述信息外,還有一部分是常量池,用于在存放編譯期生成的各種字面量(Literal)和符號引用(Symbolic References),這部分的內(nèi)容在類加載以后進入運行時常量池中存放。
字面量比較好理解,是Java語言層面的常量,例如文本字符串,聲明為final的變量
符號引用這個我第一時間沒看懂什么意思,其實是編譯原理的一個概念,包括以下的三種常量:
- 類和接口的全限定名
- 字段名稱和描述符
- 方法名稱和描述符
動態(tài)性,這是運行時常量池的一個重要的特性,在運行期間也可以將新的常量放進常量區(qū)(包括基本包裝類和String,也可以調(diào)用intern()將String強制放進常量池)
為什么需要運行時常量池呢?
Integer a = 23;//在編譯的時候會變成Integer i1=Integer.valueOf(40);使用的是線程池里面的對象 Integer b = new Integer(23);//創(chuàng)建了新的對象
ps.我感覺這個的設計思路和數(shù)據(jù)庫連接池是差不多的,可以對照著去理解。
參考資料
《深入理解Java虛擬機》
總結
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對創(chuàng)新互聯(lián)的支持。
本文名稱:Java虛擬機運行時數(shù)據(jù)區(qū)域匯總
本文鏈接:http://www.chinadenli.net/article42/pgeihc.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)、定制網(wǎng)站、關鍵詞優(yōu)化、企業(yè)網(wǎng)站制作、外貿(mào)網(wǎng)站建設、網(wǎng)站內(nèi)鏈
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)