請參看:
https://zhuanlan.zhihu.com/p/25511795?comefrom=http://blogread.cn/news/ 總結的很好
https://zhuanlan.zhihu.com/p/25575446
一、前言
最近看了《深入理解java虛擬機》中內存分配和類加載兩個章節的內容,其實之前也看過這兩節,但是覺得每次看都會有收穫,這次看覺得對java虛擬機的運行時數據區瞭解的更深入了一些,對類加載的過程所做的事情和涉及到的數據區也更清楚了。
jvm體系總體分四大塊:
- 類的加載機制
- jvm內存結構
- GC算法 垃圾回收
-
GC分析 命令調優
二、總結
1、java運行時數據區:jvm內存結構
分爲五大塊:程序計數器;虛擬機棧;本地方法棧;java堆;方法區。
(1)程序計數器:線程私有,是java字節碼行號指示器;
作用:用來選取下一條要執行的字節碼的指令,像循環,跳轉、分支、異常處理、線程恢復(多線程間的切換競爭處理器)等,都需要讀取程序計數器中數據。
(2)虛擬機棧:線程私有,也稱局部變量表,爲虛擬機執行java方法(字節碼)服務;
作用:虛擬機在虛擬機棧中爲每個方法創建一個棧楨,存放局部變量表,操作數棧,動態鏈接,方法出口等信息,每個方法的調用都會對應一個棧幀出棧和入棧的過程。
(局部變量表:存放編譯器可知的java基本類型、對象引用類型(可以指向一個對象也可指向一個句柄)、和returnAddress類型(指向一條java字節碼指令)一個局部變 量空間是32位,long和double要佔用2個)
(3)本地方法棧:用來存放本地方法(native)的數據,爲虛擬機執行本地方法服務。HotSpot將虛擬機棧和本地方法棧合二爲一。
(4)java 堆:線程共享,在虛擬機啓動時創建,可通過設置 -Xmn 和 -Xms 設置最大,最小堆內存
作用:存放所有對象和數組。若空間不足,會拋出 outofmemery 和stackoverflow異常。
從內存回收的角度來看:現在GC收集器都採用分代手機算法,所以java堆還需分爲年輕代和老年代。Eden空間,From Survivor空間,To Survivor空間;
(5)方法區:線程共享,被稱爲”永久代“,但hotSpot的GC分代回收機制擴展至方法區;主要收集常量池和對類型卸載(效果不好)。
作用:用於存放虛擬機加載的類信息,常量,靜態變量,即時編譯器編譯後的代碼等。內存不足時會拋出outofmemery異常。
(6)運行時常量池:是方法區的一部分,class文件中除了存放類的版本,字段,方法等信息外,還有一個常量池,存放編譯期生成的字面量和符號引用。
作用:存放編譯期生成的字面量和符號引用。(在類加載的加載階段,虛擬機將二進制字節流加載進運行時數據區的方法區)
注意:直接內存,並不是java運行時數據區的一部分,但是也是頻繁使用的,基於通道和緩衝區的IO方式。NIO; 內存不夠會報 outofmemery異常。
使用實例:下面通過 一個對象的創建過程 來看看虛擬機是怎樣利用這些運行時數據區的:
當虛擬機遇到一個new指令時,首先到常量池中檢查該符號引用(若找不到說明這個類沒有加載到內存),並檢查這個符號引用代表的類是否已經被加載,解析和初始化(若沒有,則先進行類加載),然後在java堆中分配該對象所需的內存空間(對象的大小在類加載階段確定的),然後對對象進行初始化工作。
對象內存分配方法:
指針碰撞法: 適合規整的內存;中間有個指針,使用的內存放指針的一邊,未使用過的放另一邊。
空閒列表法:適合不規整的內存,相互交錯;維護一個列表,記錄哪塊內存可用。
內存是否規整取決於:垃圾回收算法
2、類加載的過程(類的加載機制)
類加載的過程分爲 加載 ;驗證;準備;解析;初始化;
(1)加載階段:虛擬機通過累的全限定名找到對應的二進制流文件; --- 》 將二進制流文件加載到運行時數據區的方法區;----》在堆中生成一個java.lang.class對象,作爲堆中對象訪問方法區的入口。
(2)連接階段:包括驗證、準備、解析(位置不固定)
驗證:驗證文件格式(是否符合定義規範,版本信息是否正確等);元數據驗證(對類的數據類型進行語義分析); 字節碼校驗(對類的方法進行語義分析,是否安全);
準備:爲類變量分配內存,並設置初始值。初始化常量池中的靜態變量爲默認值(常量在 javac 編譯時,已經生成了constValue值了,所以在準備階段是將constantValue值賦給常量;
解析:將常量池內的符號引用轉換成直接引用,直接關聯內存;
(3)初始化(對類中的類變量和靜態語句塊賦值)
在網上關於java內存分配模型的講解真的是數不勝數,其中的源頭應該都是《深入理解java虛擬機》這本書吧。我吧這些總結起來,就是想做個記錄,以後在面試前好好看看,能快速想起來。
參考:《深入理解java虛擬機》
結合:http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html