深入理解java虛擬機器(1)-java記憶體地區

來源:互聯網
上載者:User

該篇部落格將從概念上講解Java虛擬機器記憶體的各個地區,講解這些地區的作用,服務物件以及可能產生的問題,這也是我們為我們後面瞭解Java記憶體管理做的一些準備。

Java虛擬機器在執行Java程式的過程中會吧它所管理的記憶體劃分為若干個不同的資料區域,這些地區都有各自的用途,以及建立和銷毀的時間,話不多說,直接看下圖,就是這些地區。可能之前你們只聽說過棧,堆和常量區,其實這些地區只不過是我們常用的幾個區而已,下面將對每個區做簡單介紹。
1.程式計數器

大家對這塊地區應該挺陌生的可能從來就沒聽說過,程式計數器是一塊較小的記憶體空間,他的作用就可以看做是當前線程所執行位元組碼的行號指標,用來記錄我們程式執行到哪裡了,舉個栗子:我們知道很多時候我們的程式都是多線程程式,在整個應用的運行中,線程是不斷切換的,線程A執行到方法A執行到一半,線程B又開始執行方法B,那麼當線程A又獲得資源開始執行自己的方法時,他是怎麼知道自己要從哪裡開始執行呢,所以也就引入了程式計數器,它記錄了線程A之前執行位元組碼的位置,同樣也會有相應的計數器記錄線程B執行的位置。通過這個例子你應該知道程式計數器是幹嘛的了,而且也能看出,每個線程都需要有一個獨立的程式計數器,各條線程的計數器互不影響,隔離儲存區 (Isolated Storage),我們稱這類地區為“線程私人”的記憶體。
如果線程正在執行的是一個java方法,這個計數器記錄的正在執行的虛擬機器位元組碼指令的地址,如果正在執行的是Native方法(中文名:本地方法,解釋一下,因為後面還有個本地方法棧,本地方法是指那些調用非Java代碼實現的介面,它是一個介面,它的真正實現是靠其他語言實現的,java虛擬機器中就有很多方法並不是用java語言實現的,因為有些方法可能用其他語言更高效,我們稱這類方法叫做本地方法)這個計數器值則為空白。
(敲黑板了)此記憶體地區是唯一一個在Java虛擬機器規範中沒有規定任何OutOfMemoryError情況的地區,後面你講看到的所有區都是可以出現OutOfMemoryError的。 2.Java虛擬機器棧

虛擬機器棧描述的是Java方法執行的記憶體模型(Java方法執行的時候密切相關):每個方法被執行的時候都會同時建立棧幀,用於儲存運算元棧,動態連結,方法出口,局部變數表(這也就是我們平常常說的棧,想不到吧,原來只是Java虛擬機器棧中的一個局部變數表)等資訊。每一個方法被調用直至執行完成的過程,就對應著一個棧幀在虛擬機器中從入棧到出棧的過程,所以通過這句話,你應該要認識到,該地區也應該是線程私人的,因為方法時某個線程執行的。
必須要知道的是局部變數表存放了編譯器可知的各種基礎資料型別 (Elementary Data Type),和各類對象的引用。其中64位長度long和double類型的資料會佔用2個局部變數空間,其餘的資料類型會佔用1個局部變數空間。
然後我們就來討論討論關於記憶體溢出的問題,這裡先提一下,後面還是會提到的,在Java虛擬機器規範中,對這個地區規定了兩種異常狀況:如果線程請求的棧深度大於虛擬機器所允許的深度,將拋出StackOverFlowError異常;但是一般虛擬機器都是可以動態擴充的,但是在擴充的時候如果無法申請到足夠的記憶體時就會拋出OutOfMemoryError異常。 3.本地方法棧

前面我已經簡單的介紹了什麼是本地方法了,本地方法棧和虛擬機器棧所發揮的作是非常相似的,其區別不過是虛擬機器棧是為虛擬機器執行Java方法服務,而本地方法則是為虛擬機器使用到的Native方法服務,本地方法棧地區也會拋出StackOverFlowError和OutOfMemoryError異常。肯定也是線程私人的。 4.Java堆

Java堆是Java虛擬機器所管理的記憶體中最大的一塊,是在虛擬機器啟動時就建立的,此記憶體地區的唯一目的就是存放對象執行個體,幾乎所有的對象執行個體都是在這裡分配記憶體的,後面會介紹到Java記憶體回收演算法採用的是分代收集演算法,所以將Java堆還可以細分為:新生代和老年代,在細分就是Eden空間,From Survivor空間和To Survivor空間(知道有這回事就行,後面會詳細介紹裡面的每個空間)如果堆中沒有記憶體完成執行個體分配,並且堆也無法在擴充時,將會拋出OutOfMemoryError異常。很顯然這是哥哥線程共用的記憶體地區,因為各個現在在操作對象時都是需要在堆上進行的。 5.方法區

方法區和Java堆一樣,是各個線程共用的記憶體地區,它用於儲存已被徐弩機載入的類資訊、常量、靜態變數、即及時編譯器編譯後的代碼等資料。這裡只要記住方發渠裡面有啥就行了,當方法區無法滿足記憶體配置需求時,將拋出OutOfMemoryError異常。

基本上圖上的5個區都介紹完了,這裡只需要知道每個區都是存放什麼的就行,後面再虛擬機器記憶體回收與分配時會詳細的設計到每個區的知識點。後面還有2個地區是我們以後可能會遇到的,這裡也就提一下。
(1)運行時常量池
運行時常量池是方法區的一部分,主要就是用來存放編譯器存放的字面量和符號引用。
運行時常量池相對於Class檔案常量池的另一個重要特徵就是具備動態性,Java語言不要求常量一定只能在編譯器產生,也就是並非預植入Class檔案中常量池的內容才能進入方法區運行時,運行期間也可能將新的常量放入池中,這種特性被開發人員利用的比較多的便是String類的intern()方法(該方法,在執行的時候會判斷String常量池中是否有該對象,如果已經存在則直接返回該對象,如果沒有則建立,這裡jdk6和jdk7還有點不一樣,有興趣的可以去瞭解下這個方法)
(2)直接記憶體
直接記憶體並不是虛擬機器運行時資料區的一部分,也不是Java虛擬機器規範中定義的記憶體地區,但是這部分記憶體也被頻繁的使用,而且也可能導致OutOfMemoryError異常出現。
在jdk1.4引入了NIO(New Input/output)類,引入了一種基於通道與緩衝區的I/O方式,他可以使用Native函數庫直接分配堆外記憶體,然後通過一個儲存在Java堆中裡面的DirectByteBuffer對象作為這塊記憶體的引用進行操作,這樣能在一些情境中顯著的提高效能,因為避免了在Java堆和Native堆中來回複製資料。
伺服器管理員配置虛擬機器參數時,一般會根據世界的記憶體設定-Xmx等參數資訊,但經常會忽略掉直接記憶體,使得各個記憶體地區的的總和大於實體記憶體限制,從而導致擴充時出現OutOfMemoryError異常。 6.舉個栗子複習下我們的記憶體地區(對象訪問)

Object obj = new Object();
假設這段代碼在方法體中,當線程執行到該代碼時,記憶體中是怎樣的一個分配形式呢,首先 Object obj將會反映到Java棧的本地變數表中,作為一個reference類型資料出現,而 new Object()這部分語義將會反映到Java堆中,形成一Block Storage了Objcet類型所有執行個體資料值的結構化記憶體,另外,在Java堆中還必須包含能查到此物件類型資料(如物件類型,父類,實現的介面,方法等)的地址資訊,而這些類型資料是儲存在方法區中的。

前面提到了,通過引用去指向對象,但是沒有提到引用通過什麼方式去指向對象,現在主流的方式有兩種,一種是控制代碼式,一種是直接指標。
1.控制代碼式:控制代碼式就相當於找個中介控制代碼(位置在堆中的控制代碼池中)而已,引用儲存的是控制代碼的地址,控制代碼再儲存物件執行個體資料和物件類型資料的地址。這樣引用就可以找到對象所有的資訊了。
2.直接指標訪問方式,引用直接儲存物件地址(執行個體資料地址),然後執行個體資料裡面再存放類型資料的指標,指向類型資料。這樣也完成了引用找到對象的所有資訊。
兩種方式各有優勢,使用控制代碼訪問的方式最大的好處就是reference中儲存的是穩定的控制代碼地址,在對象移動的時候只需要改變控制代碼中的執行個體資料指標,而本身的reference不需要改變。直接指標的好處就是速度過,因為避免的中間環節嘛。 前面在介紹各個區的時候,也把每個區可能產生記憶體溢出的原因說了下,所以如果有人問道為什麼會產生記憶體溢出,應該知道怎麼答了,我的理解就是先大概說就是,虛擬機器在執行程式的過程中請求不到足夠的記憶體會導致記憶體溢出,再細化的話就是每個區裡面是如何導致記憶體溢出的了。

此篇也是為下一篇介紹java虛擬機器的另一個重要領域“垃圾收集器與記憶體配置策略打下基礎”,所以想瞭解下一章節必須要先瞭解好Java的記憶體地區劃分。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.