天天學習一點JVM之:JAVA內存區域淺析

關於JVM系列的文章,都是在讀了《深刻理解java虛擬機》一書以後的讀書筆記總結。java

對於不少android的初學者來講,JVM知識多是至關薄弱的一塊知識。但是若是你須要到公司入職、你要提升本身駕馭java的能力,那麼JVM倒是絕對不可忽視的一個環節。最基本JAVA內存區域、垃圾回收機制和算法、類加載等等都是必須掌握的內容。android

接下來本身會寫一些本身的讀書筆記,跟你們一塊兒共享一些比較簡單又應該掌握的JVM的知識(可是對於JVM的內部更深層次的知識不會去討論,由於本身在那些方面的知識真的只是皮毛,還要好好深刻學習)。算法

首先,看圖說話(下圖是java虛擬機運行時數據區圖):學習

根據上圖,咱們能夠發現java虛擬機運行時內存共劃分紅了5個區,分別是:方法區(method area)、堆(heap)、虛擬機棧(vm stack)、本地方法棧(native method stack)和程序計數器(program counter register).其中,方法區和堆屬於全部線程共享的內存區域。this

程序計數器

從名字咱們大概能夠看到,這個實際上是用來指示當前虛擬機所執行的字節碼所在的指令地址(對於native方法而言,這個內存的值是空)。線程

爲了在線程切換的時候,可以正確加載線程的執行位置,就須要根據這個計數器來指示,所以這個內存區是線程私有的,每一個線程都會具備本身的程序計數器,互不影響。指針

java虛擬機棧

虛擬機棧(也就是咱們一般論述的java堆棧中的「棧」),它描述的是java方法的執行的內存模型,它是一個棧,棧裏面的存放的元素咱們稱之爲棧幀。所以每一個方法的生命週期其實就是棧幀的出棧和入棧道過程。棧幀的具體內容以下圖所示:cdn

由上圖咱們能夠發現棧幀裏面包含了局部變量表、操做數棧、動態鏈接、返回地址以及其餘的一些額外信息等。其中,在程序編譯的時候,就已經肯定了局部變量表、和操做數棧的大小(棧幀佔用內存的大小在編譯的時候就已經肯定)對象

  • 局部變量表blog

    局部變量表是一組變量值存儲空間,用於存放方法參數和方法內部定義的局部變量。包括編譯期間可知的各類基本數據類型(boolean、byte、short、int、float、char、long、double,其中long和double使用了兩個局部變量空間來表示)、對象引用類型(對象實例的引用(相似於指針),經過它能夠能直接或者間接的查找到對象在堆中數據存放的起始地址索引,而且能查找到對象所屬類型在方法區中的存儲的類型信息)和returnAddress類型。

    虛擬機經過索引定位的方式使用局部變量表,索引值的範圍是0-局部變量表最大的slot(局部變量表的最小容量單位,一個slot能夠存儲除long和double之外的任意一個基本數據類型)數量。在執行實例方法(即非static限定的方法)的時候,局部變量表的第0個slot默認是用於傳遞方法所屬對象的實例的引用(也就是咱們使用的this對象),其他參數則按照參數表順序排列。

  • 操做數棧

    一個方法剛開始執行的時候,操做數棧爲空,在執行過程當中,各類字節碼指令會進行入棧和出棧的操做(好比算術運算的時候和方法調用的時候)。值得注意的是,操做數棧中的元素類型必須於字節碼指令序列嚴格匹配。

本地方法棧

和java虛擬機棧相相似,只是虛擬機棧是爲java虛擬機執行java方法服務的,而本地方法棧是爲虛擬機使用native方法服務的。

堆是全部線程共享的一塊內存區域,在虛擬機啓動的時候就被建立出來。這片內存區用於存放對象實例,幾乎全部的對象實例都在這裏分配內存。堆區是java虛擬機垃圾收集器管理的主要區域。

方法區

方法區也是屬於線程共享的一塊內存區域,它用於存儲已被java虛擬機加載的類信息、常量、靜態變量、即便編譯器編譯後的代碼等數據。

  • 運行時常量池

    方法區的一部分,用於存放編譯期生成的各類字面量和符號引用。

整體的內容大概就這麼多,若是你有其餘想要了解的東西,歡迎評論一塊兒學習。若是你喜歡這篇文章,歡迎點贊收藏,也歡迎你關注我,接下來本身都會利用下班時間寫一些本身的實踐經驗和學習分享。最後,感謝你寶貴的時間閱讀這篇文章!

相關文章
相關標籤/搜索