Jvm基礎(1)-Java運行時數據區

轉載自:http://www.cnblogs.com/wardensky/p/4162121.html

最近在看《深入理解Java虛擬機》,裏面講到了Java運行時數據區,這是Jvm基本知識,把讀書筆記記錄在此。這些知識屬於常識,都能查到的,如果我有理解不對的地方,還請指出。

 

首先把圖貼上來,圖來自JVM Runtime Data Areas(運行時數據區),感謝。

 

由上圖可知,Java運行時數據區域包括程序計數器、Java虛擬機棧、本地方法棧、Java堆、方法區。

1. 程序計數器

程序計數器用來記錄下一條字節碼指令,因爲CPU是要輪轉的,在切換回來之後,Java能夠找到下一條要執行的指令。如果是多線程程序,那麼,每一個線程會有一個獨立的程序計數器。【我疑惑的是不知道這個具體怎麼設計的,如果一個有幾十萬線程的程序會不會有問題?】此內存區域是唯一一個不定義OutOfMemoryError的區域。

另外,比較好玩的是,其英文是Program Counter Register,說到底是一個寄存器,翻譯成計數器有點不準確。

 

2.Java虛擬機棧

Java虛擬機棧就是平常說的棧,我理解棧主要存儲方法相關的內容,如方法參數、方法中局部變量等。調用方法時,內容壓入棧中,方法返回時,從棧中彈出。棧裏面還細分爲局部變量區、操作數棧、動態連接等。其中局部變量區存儲了編譯期可知的各種基本數據類型(boolean、byte、char、short、int、float、long、double)、對象引用等。其中64位長度的long和double類型的數據會佔用2個局部變量空間(Slot),其餘的數據類型只佔用1個。【這個要特別注意,這個會引起一個線程同步的問題】

 

3.本地方法棧

本地方法指的是Java實現不了,用C或C++實現的方法。關於本地方法,請參考java native方法及JNI實例

 

4.Java堆

Java堆是最值得關注的地方,因爲這個地方經常拋出內存不足的異常。【我在項目中就遇到過很多次,都是內存泄漏的問題】

Java堆是代碼裏面存放變量的地方,比如定義了一個字符串,那麼其真實地址就存在堆中。Java堆可以分爲新生代(New Generation)和老年代(Old Generation/Tenuring Generation),有的又分爲Eden空間、From Survivor空間、To Survivor空間等。其主要思想與Java GC有關係,即大部分對象的存活時間都比較短,如果某一個對象存活時間比較長,就把他移到另外一個區域。這樣做GC的成本比較低。【關於這個話題,我會單獨寫一篇】

 

5.方法區

方法區存儲的是類的一些基本信息,如類的常量池、靜態變量等。【標準說法是:類及其父類的全限定名(java.lang.Object沒有父類)、類的類型(Class or Interface)、訪問修飾符(public, abstract, final)、實現的接口的全限定名的列表、常量池、字段信息、方法信息、靜態變量、ClassLoader引用、Class引用】

可以這樣理解,如果定義了一個類,其中有一個靜態變量,那麼在new這個類的時候,靜態變量會放在方法區,實例的其它部分會放在Java堆;如果又new了這個類,那麼方法區的靜態變量不變,在Java堆裏面會有一塊新的內存放實例。

 

以上就是Java運行時數據區,瞭解這部分內容會對後續的學習(如GC)有一定的幫助。

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