1、前言
自從入行以來,一直沒有深刻學習過JVM,雖然看過好些書、博客也有一點了解,但都不是專門講JVM的,因此對JVM停留在淺顯的瞭解上,沒有深刻了解過,一直想深刻學習,不過想學的東西太多了,這就致使JVM成了本身的短板,前些日子在網上看到了救火大隊長的《從零開始帶你成爲JVM實戰高手》專欄正在更新中,決定藉此機會好好深刻學習一下,順便把學習心得結合之前學習的知識記錄下來,加深本身的理解。java
2、JVM加載類的過程
- 加載,加載爲按需加載,主線程須要用到一個類纔開始加載一個類。
- 驗證,簡而言之就是校驗class內容是否符合指定規範
- 準備,爲類變量分配內存空間,並初始默認值。
- 初始化,執行類的初始化代碼(靜態代碼塊,靜態賦值代碼),注:初始化會檢驗父類是否初始化,沒有則必須先初始化父類。
- 使用
- 卸載
3、類加載器
種類
- 啓動類加載器-Bootstrap ClassLoader,用於加載Java核心類庫-java安裝目錄下的lib目錄下的class。
- 擴展類加載器-Extension ClassLoader,用於加載java下的一些擴展類庫-java安裝目錄lib\ext下的class。
- 應用程序類加載器-Application ClassLoader,加載項目ClassPath下所的class。
- 自定義類加載器,本身定義的類加載器
雙親委派機制
意思就是即優先讓父ClassLoader去加載。緣由是避免重複加載,保證應用的classPath下的Class對象在內存中的惟一性。web
層次圖
tomcat破壞雙親委派
tomcat做爲java編碼的web容器,自己也是在jvm中運行,怎麼讓基於tomcat容器的各個web應用正常運行,使得各個web應用包含的應用的class不會亂套,必須破壞雙親委派機制,爲每個web應用的class都用不一樣的類加載器去加載。數據庫
- tomcat的類加載器層次圖
其中:數組
common、catalina、shared負責加載tomcat本身的核心類庫,webApp加載web應用的class(隔離web應用引用的三方類庫),jsp加載器加載JSP(每一個JSP文件都對應一個Jsp類加載器,jsp加載器支持熱加載,即Jsp只要修改,就從新加載一次覆蓋原來的jsp)。緩存
經過tomcat的類加載機制,能夠達成如下目標:tomcat
- tomcat支持各個web引用中不一樣版本的三方類庫相互隔離。
- 同一個第三方類庫的相同版本在不一樣web應用能夠共享。
- tomcat自身依賴的類庫須要與應用依賴的類庫隔離 。
- jsp須要支持修改後不用重啓tomcat便可生效 爲了上面類加載隔離和類更新不用重啓,定製開發各類的類加載器。
自定義類加載器的做用
- 實際中,能夠從Web服務器、數據庫或緩存服務器獲取bytes數組,這就不是系統類加載器能作到的了。
- 能夠從不一樣的路徑中獲取同一個類的不一樣class對象,能夠實現隔離,一個複雜的程序,內部可能按模塊組織,不一樣模塊可能使用同一個類,但使用的是不一樣版本,若是使用同一個類加載器,它們是沒法共存的,不一樣模塊使用不一樣的類加載器就能夠實現隔離,Tomcat使用它隔離不一樣的Web應用,OSGI使用它隔離不一樣模塊。
- 能夠實現熱部署。使用同一個ClassLoader,類只會被加載一次,加載後,即便class文件已經變了,再次加載,獲得的也仍是原來的Class對象,而使用自定義類加載器,則能夠先建立一個新的ClassLoader,再用它加載Class,獲得的Class對象就是新的,從而實現動態更新。
4、JVM內存區域劃分
方法區(1.8以後叫metaspace-元數據空間)
存放類的元數據信息,能夠理解爲反射獲取的Class對象的哪些信息。服務器
程序計數器
- 記錄當前執行的class文件中字節碼指令的位置
- 與線程是一對一的關係,每一個線程都會有本身的一個程序計數器
棧
一個程序計數器對應一個線程、一個線程對應一個棧、一個棧由一個個棧幀組成,一個方法對應一個棧幀,棧幀包含局部變量表、操做數棧、動態連接、方法出口(至關於結束方法時須要跳轉的位置)。棧幀在調用方法的時候進棧,方法結束的時候出棧。jvm
堆
- 存放對象數據(上述棧中只存在對象的引用(即堆內存中對象的地址)或基本數據類型的值)
- 全部線程共享
- 當引用變量地址數據出棧時,堆中的內存釋放由JVM控制回收
其餘內存區域
- 執行native方法會有線程對應的本地方法棧。
- NIO中ByteBuffer類方法:allocateDirect(int capacity)-堆外分配內存空間返回DirectBuffer,經過DirectBuffer的Api能夠操做堆外內存。
圖示
4、小結
這篇文章是JVM總結的第一篇博客,可能會以爲有點Low,不過寫這篇博客也是想從零開始學習總結一番,就這樣吧。 文中大部份內容來、圖片(我也本身畫過,可是太醜了,就不貼了)來源於救火大隊長的《從零開始帶你成爲JVM實戰高手》專欄文章所學筆記心得,地址在下面,有興趣的朋友能夠去看看(是收費專欄,不過較便宜)。jsp