jvm原理及優化
jvm的啟動:
裝載配置 => 載入類 => 執行主方法
由類載入器載入類檔案到記憶體,包括堆,棧,方法區以及本地方法區等等,,,
方法區儲存類的資訊(常量池,欄位方法等資訊等等)
堆包含了應用程式中的系統物件
棧是執行緒私有,由一系列棧幀組成,每一次方法呼叫都建立一個幀,壓棧。棧包括了局部變數,運算元和常量池指標等
執行緒執行時根據變數或引用(棧)去堆(物件)內查詢,根據堆內資訊到方法區內查詢執行
每個執行緒由私有的執行緒工作記憶體,它和主記憶體進行互動。
volatile 保證了執行緒之間變數的可見性
jvm的一些配置引數:
java -jar demo.jar -XX:+printGC 列印一些gc資訊
-XX:+PrintGCDetails –列印GC詳細資訊
-XX:+PrintGCTimeStamps –列印CG發生的時間戳
-Xloggc:~/gc.log –指定GC log的位置,以檔案輸出
-XX:+TraceClassLoading –監控類的載入
-XX:+PrintClassHistogram 垃圾清理之前列印直方圖
-Xmx –Xms 指定最大和最小的堆記憶體
-XX:OnOutOfMemoryError –在OOM時,執行一些操作
官方推薦新生代佔堆的3/8
倖存代佔新生代的1/10
-XX:PermSize -XX:MaxPermSize 永久代最開始和最大
-Xss 執行緒的棧大小
gc的演算法種類
(引用計數)引用計數器的實現很簡單,對於一個物件A,只要有任何一個物件引用了A,則A的引用計數器就加1,當引用失效時,引用計數器就減1。只要物件A的引用計數器的值為0,則物件A就不可能再被使用
–引用和去引用伴隨加法和減法,影響效能
–很難處理迴圈引用
標記-清除演算法是現代垃圾回收演算法的思想基礎。標記
標記-壓縮演算法適合用於存活物件較多的場合,如老年代。它在標記-清除演算法的基礎上做了一些優化。和標記-清除演算法一樣,標記-壓縮演算法也首先需要從根節點開始,對所有可達物件做一次標記。但之後,它並不簡單的清理未標記的物件,而是將所有的存活物件壓縮到記憶體的一端。之後,清理邊界外所有的空間
將原有的記憶體空間分為兩塊,每次只使用其中一塊,在垃圾回收時,將正在使用的記憶體中的存活物件複製到未使用的記憶體塊中,之後,清除正在使用的記憶體塊中的所有物件,交換兩個記憶體的角色,完成垃圾回收(不適用於存活物件較多的場合 如老年代)
序列收集
並行
類載入器流程
載入,連線(驗證,準備,解析),初始化
載入:獲取二進位制流,轉換為方法區的資料結構,在堆中生成對應的物件
連線.驗證:檔案格式,元資料資訊,位元組碼驗證等
連線.準備:分配記憶體,設定初始值,static final直接賦值(常量池)
連線.解析:引用的解析
初始化:靜態程式碼塊或者子類構造等
ClassLoader在載入階段,負責將位元組碼檔案載入到記憶體中,可定製
BootStrap Extension App Custom
從右向左查詢是否已經載入,從左向右載入
鎖的顆粒度