深入理解JVM--我的學習筆記

        現在轉行做Java開發,相信有過Java開發經驗的人都知道,做Java開發要學很多東西:JavaSE,JVM,設計模式,線程併發以及鎖原理等等。雖然不多,但內容很有深度,需要反覆的斟酌纔能有更深一步的理解。本人近來在看《深入理解JVM》,但是怕看後又忘了或是理解不到位,不夠深入。所以把看過的東西用自己的語言寫在這裏,共勉。

        首先說一下爲什麼要學習JVM。JVM是Java程序運行鎖必須的環境,沒有它Java就不能運行。Java程序運行時與之相關的class,instance,內存都有JVM管理,所以理解了JVM的運行機制,出現BUG時可以很快的定位Bug的原因和位置;這也是通向Java架構師必須要走的一步。另外,在Java面試的過程中,不少的技術經理也都會問到關於JVM的一些東西,回答的不好基本就沒戲了。所以爲了工作,爲了興趣都應該學習JVM的運行機制。好了,閒話說道這裏,馬上進入正題。(文章會不定時更新,歡迎各位批評指正,共同進步)。

        第一節  JVM的內存管理

         JVM的內存對計算機的物理內存做了映射處理,即JVM的內存的不同部分可能對應着物理內存的運存、寄存器或告訴緩存(想了解具體映射關係的同學,可以參考相應的博文,不過意義不大)。

      JVM將內存劃分爲六個部分:Java堆,方法區,程序計數器區,虛擬機棧(VM Stack),本地方法棧(native stack),直接內存區(direct memory)。下面具體介紹各個部分。

      (1)Java堆。這個區域應該是每一個Java程序員都知道的地方,你創建的每一個對象都存放在這個區域。GC的大部分操作都是在這裏,畢竟GC的主要工作就是釋放無用的對象實例。這個區域是線程共享的。

       (2)方法區。這個區域也是線程共享的(就這倆是想成共享的)。進一步可以分爲常量池、靜態區、jit編譯器編譯過的代碼等等。常量池又分爲Class常量池和字符串常量池,其中字符串常量池是可以動態擴展的(運行時產生的字符串常量也添加到這裏);Class常量池裏存放着程序中每一個用到的類的Class文件(這個會在後邊的對象佈局中用到);靜態區存放的是靜態成員包括靜態域和靜態方法;

       (3)程序計數器區。該區域是線程私有的(VM stack,native stack也是線程私有的),它可以看做的字節碼在運行時的指示器。因爲操作系統的時間片運行原理,每個線程在自己的時間片用完後都要掛起,以便其他線程或進程能運行,所以要對線程進行現場保護,該區域也就需要線程私有了。

       (4)虛擬機棧。這個區域是爲Java方法服務的。方法在執行時所需要的參數類型,返回類型等都在這裏,其中最重要的是變量符號表,這個符號表中存放了方法的基本類型,引用類型和returnValue類型,其大小在編譯時期就已確定,運行時大小不變。

       (5)本地方法棧。這個區域和虛擬機棧類似,只不過這個棧時爲本地方法服務的。但不同的虛擬機又不同的實現,sun公司的Hotspot將這兩個棧合二爲一了。

       (6)直接內存區。這個區不是JVM內存的一部分,也不是JVM規範的一部分,其大小不受Java堆大小的影響,理論上可以任意大小,但是計算機的物理內存和交換區大小有限,所以還是受物理機的限制。這部分也是經常被訪問的地方,也是在考慮JVM內存大小時容易忽略的地方。應注意 !

       簡單總結:線程共享的區域----Java堆和方法區;線程私有的區域----程序計數器區,虛擬機棧,本地方法棧;

       GC經常訪問的是Java堆,堆方法區的訪問效果也不錯,主要是涉及到類的卸載。

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