Java的內存區域劃分

內存分區簡介

老生常談的問題了,雖然網上一搜一大把,也很詳細,但是我還是想寫一寫,通過自己的總結整理,加深一下印象。

我不知道學習Java內存分區有什麼實際作用,但它就是像常識一樣,一個使用Java語言的人不知道內存分區總感覺差點意思。

Java程序是運行在JVM虛擬機上的。Java虛擬機在運行程序時會把其自動管理的內存劃分爲以下幾個區域:

方法區、堆、程序計數器、虛擬機棧、本地方法棧。

其中方法區和堆是所有線程共享的,而程序計數器、虛擬機棧和本地方法棧是每個線程獨立享有的。

這個不需要死記硬背,當我們瞭解了這幾個區域不同的功能之後,就知道爲什麼有些內存區域是線程共享,而另外一些是線程私有的了。

各區域職責劃分

方法區(Method Area)

方法區屬於線程共享的內存區域,《Java虛擬機規範》中將其描述爲堆的一個邏輯部分,又稱Non-Heap(非堆,目的是與Java堆區分開來),主要用於存儲已被虛擬機加載的類型信息、常量、靜態變量、即時編譯器編譯後的代碼緩存等數據。

拿做菜打個比方,我理解方法區就好比一個食譜,它裏面記錄着做菜需要用的食材,加工方式等等。既然是菜譜,那就是公共的東西,不能修改,沒必要每個線程都有一份,大家誰需要誰來查看就好了。所以它是線程共享的。

JVM堆(Java Heap)

Java 堆在虛擬機啓動時創建,是Java 虛擬機所管理的內存中最大的一塊,主要用於存放對象實例,幾乎所有的對象實例都在這裏分配內存,是垃圾收集器管理的主要區域,因此很多時候也被稱做GC 堆(Garbage Collection),如果在堆中沒有內存完成實例分配,並且堆也無法再擴展時,將會拋出OutOfMemoryError 異常。

這次有點牽強,但還是可以拿做菜打比方。

先說說面向對象。堆是用來存儲對象的,對象是什麼呢?對象是幫助我們做事情的東西,很多人拿洗衣服來說明面向對象編程。如果我們面向過程洗衣服,那麼我們需要揉搓、洗滌、擰水、晾曬,每一步都要親力親爲;而當我們面向對象時,只需要將衣服扔進洗衣機這個對象,剩下的事就不用管了,輕鬆省力。所以對象,就是幫助我們做事的工具。

在做菜中,對象可以理解爲電烤箱、菜刀,這種工具,那麼在程序中,堆就是用來存儲這些工具的,每個人都可以使用這些工具,不會亂套,所以堆也是線程共享的。

程序計數器(Program Counter Register):

程序計數器屬於線程私有的數據區域,是一小塊內存空間,主要代表當前線程所執行的字節碼行號指示器。字節碼解釋器工作時,通過改變這個計數器的值來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能都需要依賴這個計數器來完成。

用做菜來說,程序計數器記錄的是你做菜做到了哪個環節了,顯然不可能每個廚師都恰好在做相同的事,大家需要自己把控自己的進度,所以程序計數器是線程私有的。

虛擬機棧(Java Virtual Machine Stacks):

屬於線程私有的數據區域,與線程同時創建,總數與線程關聯,代表Java方法執行的內存模型。每個方法執行時都會創建一個棧楨來存儲方法的的變量表、操作數棧、動態鏈接方法、返回值、返回地址等信息。每個方法從調用直結束就對於一個棧楨在虛擬機棧中的入棧和出棧過程。

這個對應的就是做菜的過程了,比如做一道菜需要三步,準備材料→炒菜→出鍋。拿第一步舉例,首先要準備材料,準備材料這個方法就要入棧了,入棧後發現,需要先把菜洗了,那麼洗菜這個方法也要進棧,然後又發現需要先摘菜葉子。我們假定摘菜葉之前沒有其他操作了,那麼之後從棧頂開始先執行摘菜方法,然後摘菜方法彈出,然後執行洗菜方法,然後洗菜方法彈出,再執行準備材料方法,是一個後進先出的順序,前一個彈出,後一個再執行。既然都已經具體到過程了,自然每個線程是要隔離開的,不能相互干擾。

本地方法棧(Native Method Stacks):

本地方法棧跟 Java 虛擬機棧的功能類似,Java 虛擬機棧用於管理 Java函數的調用,而本地方法棧則用於管理本地方法的調用。但本地方法並不是 用 Java 實現的,而是由 C 語言實現的(比如Object.hashcode 方法)。 本地方法棧是和虛擬機棧非常相似的一個區域,它服務的對象是 native方法。你甚至可以認爲虛擬機棧和本地方法棧是同一個區域。

虛擬機規範無強制規定,各版本虛擬機自由實現 ,HotSpot 直接把本地方法棧和虛擬機棧合二爲一 。

本地方法棧屬於線程私有的數據區域,這部分主要與虛擬機用到的 Native 方法相關,一般情況下,我們無需關心此區域。

簡單總結一下

Java內存區域劃分爲5個,重點關注的是堆、棧、和方法區,程序計數器與本地方法棧一般不大涉及到。

方法區與堆是所有線程共享的,其餘三個是每個線程私有的。

堆是兵器庫,垃圾回收的主要區域,方法區是指揮官,棧是管幹活的。

如果我的理解和表達有不對的地方,歡迎大佬們斧正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章