續 My java——JVM(內存)二 寫了一點JVM內存的一些操做的方法,和引出內存的分類。 html
是呀,java內存是咱們在java編程中不多考慮到的,也沒用真正的管理過。也許都知道JVM有本身的垃圾回收機制,因此在編程中沒有考慮過,的確JVM幫咱們解決了在C++中最頭痛的事情。但這裏仍是要拋出一點JVM內存的一點知識,以便明白java程序在JVM運行原理。
關於JVM的內存有不少不一樣的說法和版本,,反正我是是弄混了的,在上篇博文中也提到存儲的分類。也許是JVM有不一樣的版本吧,因此有不少不一樣的說法。 java
從上圖能夠見到的看出分爲五個部分,兩個是線程共享區,三個線程隔離區。
程序員
|
|
PROGEAM COUNTER REGISTER |
線程私有 |
JAVA STACK |
線程私有 |
NATIVE METHOD STACK |
線程私有 |
HEAP |
線程共享 |
MEATHOD AREA |
線程共享 |
一、程序計數器
記錄java線程的標記,能夠簡單理解成一個線程的ID,和記錄該線程的運行情況。
二、JVM棧
本地變量表存放了編譯期可知的各類標量類型(boolean、byte、char、short、int、float、long、double)、對象引用(不是對象自己,僅僅是一個引用指針)、方法返回地址等。生命週期與線程的週期同樣,線程解釋,棧的內存就清空。
三、本地棧
本地方法棧與VM棧所發揮做用是相似的,只不過VM棧爲虛擬機運行VM原語服務,而本地方法棧是爲虛擬機使用到的Native方法服務,因此能夠理解成與java程序五個。
四、堆
Java堆是虛擬機管理最大的一塊內存,常常有人把Java 內存區分爲堆內存(Heap)和棧內存(Stack),這種分法比較粗糙,Java 內存區域的劃分實際上遠比這複雜。這種劃分方式的流行只能說明大多數程序員最關注的、與對象內存分配關係最密切的內存區域是這兩塊。這樣分也讓程序員更加清楚,String s = new String("mylove");等號前的存儲在棧中,等號後的存儲在堆中,這也許是一個簡單的理解。JVM內存回收主要就是回收堆的。經過-Xmx和-Xms控制的就是堆的大小。
五、方法區
方法區中存放了每一個Class的結構信息,包括常量池、字段描述、方法描述等等。VM Space描述中對這個區域的限制很是寬鬆,除了和Java堆同樣不須要連續的內存,也能夠選擇固定大小或者可擴展外,甚至能夠選擇不實現垃圾收集。相對來講,垃圾收集行爲在這個區域是相對比較少發生的,但並非某些描述那樣永久代不會發生GC(至少對當前主流的商業JVM實現來講是如此),這裏的GC主要是對常量池的回收和對類的卸載,雖然回收的「成績」通常也比較差強人意,尤爲是類卸載,條件至關苛刻。
非運行時內存區:
六、運行常量池
Class文件中除了有類的版本、字段、方法、接口等描述等信息外,還有一項信息是常量表(constant_pool table),用於存放編譯期已可知的常量,這部份內容將在類加載後進入方法區(永久代)存放。可是Java語言並不要求常量必定只有編譯期預置入Class的常量表的內容才能進入方法區常量池,運行期間也可將新內容放入常量池(最典型的String.intern()方法)。
七、直接內存
直接內存並非虛擬機運行時數據區的一部分,它根本就是本機內存而不是VM直接管理的區域。
參考:http://blog.sina.com.cn/s/blog_67fdef9001011nyv.html