0010 Java JVM虛擬機器7塊記憶體區劃分【入門】__Java

來源:互聯網
上載者:User

順口溜:器池堆,棧棧區區

                棄池堆,站站曲曲(一離開衛生間,肚子疼的站不起身)

 

Java中記憶體的管理機制是通過JVM來自動管理的。瞭解JVM的基礎原理有利於進一步理解Java。

我們首先要瞭解java記憶體的分配機制,在java虛擬機器規範裡,JVM被分為7個記憶體地區。

虛擬機器規範中的7個記憶體地區分別是三個線程私人的和四個線程共用的記憶體區。

線程私人的記憶體地區:線程私人的記憶體地區與線程具有相同的生命週期,它們分別是:指令計數器、線程棧和本地線程棧。

四個共用區:四個共用區是所有線程共用的,在JVM啟動時就會分配,分別是:方法區、 常量池、直接記憶體區和堆(即我們通常所說的JVM的記憶體分為堆和棧中的堆,後者就是前面的線程棧)。

1 、指令計數器。

我們都知道java的多線程是通過JVM切換時間片啟動並執行,因此每個線程在某個時刻可能在運行也可能被掛起,那麼當線程掛起之後,JVM再次調度它時怎麼知道該線程要運行那條位元組碼指令呢。這就需要一個與該線程相關的記憶體地區記錄該線程下一條指令,而指令計數器就是實現這種功能的記憶體地區。有多少線程在編譯時間是不確定的,因此該地區也沒有辦法在編譯時間分配,只能在建立線程時分配,所以說該地區是線程私人的,該地區只是指令的計數,佔用的空間非常少,所以虛擬機器規範中沒有為該地區規定OutofMemoryError。

2、線程棧(虛擬機器棧)。

每個棧空間的預設大小為0.5M,在1.7裡調整為1M,每調用一次方法就會壓入一個棧幀,如果壓入的棧幀深度過大,即方法調用層次過深,就會拋出StackOverFlow,,SOF最常見的情境就是遞迴中,當遞迴沒辦法退出時,就會拋此異常,Hotspot提供了參數設定改地區的大小,使用-Xss:xxK,就可以修改預設大小。

3、本地線程棧。

該地區主要是給調用本地方法的線程分配的,該地區和線程棧的最大區別就是,在該線程的申請的記憶體不受GC管理,需要調用者自己管理,JDK中的Math類的大部分方法都是本地方法,一個值得注意的問題是,在執行本地方法時,並不是運行位元組碼,所以之前所說的指令計數器是沒法記錄下一條位元組碼指令的,當執行本地方法時,指令計數器置為undefined。

本地方法棧與線程棧所發揮的作用是非常相似的,其區別在於線程棧為虛擬機器執行Java方法服務,而本地方方法棧是為虛擬機器使用到的Native方法服務。

4、方法區。

這塊地區是用來存放JVM裝載的class的類資訊,包括:類的方法、靜態變數、類型資訊(介面/父類),我們使用反射技術時,所需的資訊就是從這裡擷取的。

一般來說這個地區的記憶體回收目標是針對常量池的回收和對類型的卸載。

5、常量池。

變數用final修飾,不能再修改它的值,所以就成為常量,而這常量將會存放在常量區,這些常量在編譯時間就知道佔用空間的大小,但並不是說明該地區編譯就固定了,運行期也可以修改常量池的大小,典型的情境是在使用String時,你可以調用String的 intern(),JVM會判斷當前所建立的String對象是否在常量池中,若有,則從常量區取,否則把該字元放入常量池並返回,這時就會修改常量池的大小(常量的大小是不可改變的)。

6、直接記憶體區。

直接記憶體區並不是JVM可管理的記憶體區。在JDK1.4中提供的NIO中,實現了高效的R/W操作,這種高效的R/W操作就是通過管道機制實現的,而管道機制實際上使用了本地記憶體,這樣就避免了從本地源檔案複製JVM記憶體,再從JVM複製到目標檔案的過程,直接從源檔案複製到目標檔案,JVM通過DirectByteBuffer操作直接記憶體。

==。在JDK1.4中新加入了NIO類,引入了一種基於通道與緩衝區的I/O方式,它可以使用Native函數直接分配堆外記憶體,然後通過一個儲存在Java堆裡面的DirectByteBuffer對象作為這塊記憶體的引用進行操作。這樣能在一些情境中顯著提高效能,因為避免了在Java堆和Native堆中來回複製資料。來

7、堆。

堆是JVM中的最常見的、最為熟知的記憶體區,我們通常所說的GC主要就是在這塊地區中進行的,所有的java對象都在這裡分配,這也是JVM中最大的記憶體地區,被所有線程共用,成千上萬的對象在這裡建立,也在這裡被銷毀。

對象訪問

在Java語言中,對象的訪問時如何進行的。即使最普通的對象訪問也會涉及到Java堆、Java棧、方法區這三個最重要記憶體地區,如下面這段代碼:

Object obj = new Object();

假設這句代碼出現在方法體中,那“Object obj”這部分的語義將會反映到Java棧的本地變數表中,作為一個reference類型出現。而“new Object()”這部分語義將會反映到Java堆中,形成一Block Storage了Object類型所有執行個體資料的結構化記憶體。在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.