在江湖中要練就絕世武功必須內外兼備, 精妙的招式和深厚的內功, 武功的基礎是內功。 對於武功低(就像江南七怪)的人, 招式更重要, 因為他們不能靠內功直接去傷人, 只能靠招式, 利刃上優勢來取勝了, 但是練到高手之後, 內功就更主要了。 一個內功低的人招式在奇妙也打不過一個內功高的人。 比如, 你劍法再厲害, 一劍刺過來, 別人一掌打斷你的劍, 你還怎麼使劍法, 你一掌打到一個武功高的人身上, 那人沒什麼事, 卻把你震傷了, 你還怎麼打。 同樣兩者也是相輔相成的, 內功深厚之後, 原來普通的一招一式威力也會倍增。
對於搞開發的我們其實也是一樣, 現在流行的框架越來越多, 封裝的也越來越完善, 各種框架可以搞定一切, 幾乎不用關注底層的實現, 初級程式師只要熟悉基本的使用方法, 便可以快速的開發上線;但對於高級程式師來講, 內功的修煉卻越發的重要, 比如演算法、設計模式、底層原理等, 只有把這些基礎熟練之後, 才能在開發過程中知其然知其所以然, 出現問題時能快速定位到問題的本質。
對於Java程式師來講, spring全家桶幾乎可以搞定一切, spring全家桶便是精妙的招式, jvm就是內功心法很重要的一塊, 線上出現性能問題, jvm調優更是不可回避的問題。 因此JVM基礎知識對於高級程式師的重要性不必言語,
jvm 總體梳理
jvm體系總體分四大塊:
類的載入機制
jvm記憶體結構
GC演算法 垃圾回收
GC分析 命令調優
當然這些知識點在之前的文章中都有詳細的介紹, 這裡只做主幹的梳理
這裡畫了一個思維導圖, 將所有的知識點進行了陳列, 因為圖比較大可以點擊右鍵下載了放大查看。
類的載入機制
主要關注點:
什麼是類的載入
類的生命週期
類載入器
雙親委派模型
什麼是類的載入
類的載入指的是將類的.class檔中的二進位資料讀入到記憶體中, 將其放在運行時資料區的方法區內, 然後在堆區創建一個java.lang.Class物件,
類的生命週期
類的生命週期包括這幾個部分, 載入、連接、初始化、使用和卸載, 其中前三部是類的載入的過程,如下圖;
載入, 查找並載入類的二進位資料, 在Java堆中也創建一個java.lang.Class類的物件
連接, 連接又包含三塊內容:驗證、準備、初始化。 1)驗證, 檔案格式、中繼資料、位元組碼、符號引用驗證;2)準備, 為類的靜態變數分配記憶體, 並將其初始化為預設值;3)解析, 把類中的符號引用轉換為直接引用
初始化, 為類的靜態變數賦予正確的初始值
使用, new出物件程式中使用
卸載, 執行垃圾回收
幾個小問題?
1、JVM初始化步驟 ? 2、類初始化時機 ?3、哪幾種情況下, Java虛擬機器將結束生命週期?
答案參考這篇文章jvm系列(一):java類的載入機制
類載入器
啟動類載入器:Bootstrap ClassLoader, 負責載入存放在JDKjrelib(JDK代表JDK的安裝目錄, 下同)下, 或被-Xbootclasspath參數指定的路徑中的, 並且能被虛擬機器識別的類庫
擴展類載入器:Extension ClassLoader, 該載入器由sun.misc.Launcher$ExtClassLoader實現, 它負責載入DKjrelibext目錄中, 或者由java.ext.dirs系統變數指定的路徑中的所有類庫(如javax.*開頭的類), 開發者可以直接使用擴展類載入器。
應用程式類載入器:Application ClassLoader, 該類載入器由sun.misc.Launcher$AppClassLoader來實現, 它負責載入使用者類路徑(ClassPath)所指定的類, 開發者可以直接使用該類載入器
類載入機制
全盤負責, 當一個類載入器負責載入某個Class時, 該Class所依賴的和引用的其他Class也將由該類載入器負責載入,
父類委託, 先讓父類載入器試圖載入該類, 只有在父類載入器無法載入該類時才嘗試從自己的類路徑中載入該類
緩存機制, 緩存機制將會保證所有載入過的Class都會被緩存, 當程式中需要使用某個Class時, 類載入器先從緩存區尋找該Class, 只有緩存區不存在, 系統才會讀取該類對應的二進位資料, 並將其轉換成Class對象, 存入緩存區。 這就是為什麼修改了Class後, 必須重啟JVM, 程式的修改才會生效
jvm記憶體結構
主要關注點:
jvm記憶體結構都是什麼
物件分配規則
jvm記憶體結構
方法區和對是所有執行緒共用的記憶體區域;而java棧、本地方法棧和程式師計數器是運行是執行緒私有的記憶體區域。
Java堆(Heap),是Java虛擬機器所管理的記憶體中最大的一塊。Java堆是被所有執行緒共用的一塊記憶體區域,在虛擬機器啟動時創建。此記憶體區域的唯一目的就是存放物件實例,幾乎所有的物件實例都在這裡分配記憶體。
方法區(Method Area),方法區(Method Area)與Java堆一樣,是各個執行緒共用的記憶體區域,它用於存儲已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的代碼等資料。
程式計數器(Program Counter Register),程式計數器(Program Counter Register)是一塊較小的記憶體空間,它的作用可以看做是當前執行緒所執行的位元組碼的行號指示器。
JVM棧(JVM Stacks),與程式計數器一樣,Java虛擬機器棧(Java Virtual Machine Stacks)也是執行緒私有的,它的生命週期與執行緒相同。虛擬機器棧描述的是Java方法執行的記憶體模型:每個方法被執行的時候都會同時創建一個棧幀(Stack Frame)用於存儲區域變數表、操作棧、動態連結、方法出口等資訊。每一個方法被調用直至執行完成的過程,就對應著一個棧幀在虛擬機器棧中從入棧到出棧的過程。
本地方法棧(Native Method Stacks),本地方法棧(Native Method Stacks)與虛擬機器棧所發揮的作用是非常相似的,其區別不過是虛擬機器棧為虛擬機器執行Java方法(也就是位元組碼)服務,而本地方法棧則是為虛擬機器使用到的Native方法服務。
物件分配規則
物件優先分配在Eden區,如果Eden區沒有足夠的空間時,虛擬機器執行一次Minor GC。
大物件直接進入老年代(大物件是指需要大量連續記憶體空間的物件)。這樣做的目的是避免在Eden區和兩個Survivor區之間發生大量的記憶體拷貝(新生代採用複製演算法收集記憶體)。
長期存活的物件進入老年代。虛擬機器為每個物件定義了一個年齡計數器,如果物件經過了1次Minor GC那麼物件會進入Survivor區,之後每經過一次Minor GC那麼對象的年齡加1,知道達到閥值對象進入老年區。
動態判斷物件的年齡。如果Survivor區中相同年齡的所有物件大小的總和大於Survivor空間的一半,年齡大於或等於該年齡的物件可以直接進入老年代。
空間分配擔保。每次進行Minor GC時,JVM會計算Survivor區移至老年區的物件的平均大小,如果這個值大於老年區的剩餘值大小則進行一次Full GC,如果小於檢查HandlePromotionFailure設置,如果true則只進行Monitor GC,如果false則進行Full GC。
GC演算法 垃圾回收
主要關注點:
物件存活判斷
GC演算法
垃圾回收器
物件存活判斷
判斷物件是否存活一般有兩種方式:
引用計數:每個物件有一個引用計數屬性,新增一個引用時計數加1,引用釋放時計數減1,計數為0時可以回收。此方法簡單,無法解決物件相互迴圈引用的問題。
可達性分析(Reachability Analysis):從GC Roots開始向下搜索,搜索所走過的路徑稱為引用鏈。當一個物件到GC Roots沒有任何引用鏈相連時,則證明此物件是不可用的,不可達對象。
GC演算法
GC最基礎的演算法有三種:標記 -清除演算法、複製演算法、標記-壓縮演算法,我們常用的垃圾回收器一般都採用分代收集演算法。
標記 -清除演算法,“標記-清除”(Mark-Sweep)演算法,如它的名字一樣,演算法分為“標記”和“清除”兩個階段:首先標記出所有需要回收的物件,在標記完成後統一回收掉所有被標記的物件。
複製演算法,“複製”(Copying)的收集演算法,它將可用記憶體按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當這一塊的記憶體用完了,就將還存活著的物件複製到另外一塊上面,然後再把已使用過的記憶體空間一次清理掉。
標記-壓縮演算法,標記過程仍然與“標記-清除”演算法一樣,但後續步驟不是直接對可回收物件進行清理,而是讓所有存活的物件都向一端移動,然後直接清理掉端邊界以外的記憶體
分代收集演算法,“分代收集”(Generational Collection)演算法,把Java堆分為新生代和老年代,這樣就可以根據各個年代的特點採用最適當的收集演算法。
1、具有1-5工作經驗的,面對目前流行的技術不知從何下手,需要突破技術瓶頸的可以加群。
2、在公司待久了,過得很安逸,但跳槽時面試碰壁。需要在短時間內進修、跳槽拿高薪的可以加群。
3、如果沒有工作經驗,但基礎非常扎實,對java工作機制,常用設計思想,常用java開發框架掌握熟練的,可以加群。
4、覺得自己很牛B,一般需求都能搞定。但是所學的知識點沒有系統化,很難在技術領域繼續突破的可以加群。
5. 群號:高級架構群 647631030備註好資訊!
6.阿裡Java高級大牛直播講解知識點,分享知識,上面五大專題都是各位老師多年工作經驗的梳理和總結,帶著大家全面、科學地建立自己的技術體系和技術認知!
垃圾回收器
Serial收集器,串列收集器是最古老,最穩定以及效率高的收集器,可能會產生較長的停頓,只使用一個執行緒去回收。
ParNew收集器,ParNew收集器其實就是Serial收集器的多執行緒版本。
Parallel收集器,Parallel Scavenge收集器類似ParNew收集器,Parallel收集器更關注系統的輸送量。
Parallel Old 收集器,Parallel Old是Parallel Scavenge收集器的老年代版本,使用多執行緒和“標記-整理”演算法
CMS收集器,CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器。
G1收集器,G1 (Garbage-First)是一款面向伺服器的垃圾收集器,主要針對配備多顆處理器及大容量記憶體的機器. 以極高概率滿足GC停頓時間要求的同時,還具備高輸送量性能特徵
GC分析 命令調優
主要關注點:
GC日誌分析
調優命令
調優工具
GC日誌分析
摘錄GC日誌一部分(前部分為年輕代gc回收;後部分為full gc回收):
2016-07-05T10:43:18.093+0800: 25.395: [GC [PSYoungGen: 274931K->10738K(274944K)] 371093K->147186K(450048K), 0.0668480 secs] [Times: user=0.17 sys=0.08, real=0.07 secs]2016-07-05T10:43:18.160+0800: 25.462: [Full GC [PSYoungGen: 10738K->0K(274944K)] [ParOldGen: 136447K->140379K(302592K)] 147186K->140379K(577536K) [PSPermGen: 85411K->85376K(171008K)], 0.6763541 secs] [Times: user=1.75 sys=0.02, real=0.68 secs]通過上面日誌分析得出,PSYoungGen、ParOldGen、PSPermGen屬於Parallel收集器。其中PSYoungGen表示gc回收前後年輕代的記憶體變化;ParOldGen表示gc回收前後老年代的記憶體變化;PSPermGen表示gc回收前後永久區的記憶體變化。young gc 主要是針對年輕代進行記憶體回收比較頻繁,耗時短;full gc 會對整個堆記憶體進行回城,耗時長,因此一般儘量減少full gc的次數
young gc 日誌:
Full GC日誌:
調優命令
Sun JDK監控和故障處理命令有jps jstat jmap jhat jstack jinfo
jps,JVM Process Status Tool,顯示指定系統內所有的HotSpot虛擬機器進程。
jstat,JVM statistics Monitoring是用於監視虛擬機器運行時狀態資訊的命令,它可以顯示出虛擬機器進程中的類裝載、記憶體、垃圾收集、JIT編譯等運行資料。
jmap,JVM Memory Map命令用於生成heap dump文件
jhat,JVM Heap Analysis Tool命令是與jmap搭配使用,用來分析jmap生成的dump,jhat內置了一個微型的HTTP/HTML伺服器,生成dump的分析結果後,可以在流覽器中查看
jstack,用於生成java虛擬機器當前時刻的執行緒快照。
jinfo,JVM Configuration info 這個命令作用是即時查看和調整虛擬機器運行參數。
調優工具
常用調優工具分為兩類,jdk自帶監控工具:jconsole和jvisualvm,協力廠商有:MAT(Memory Analyzer Tool)、GChisto。
jconsole,Java Monitoring and Management Console是從java5開始,在JDK中自帶的java監控和管理主控台,用於對JVM中記憶體,執行緒和類等的監控
jvisualvm,jdk自帶全能工具,可以分析記憶體快照、執行緒快照;監控記憶體變化、GC變化等。
MAT,Memory Analyzer Tool,一個基於Eclipse的記憶體分析工具,是一個快速、功能豐富的Java heap分析工具,它可以説明我們查找記憶體洩漏和減少記憶體消耗
GChisto,一款專業分析gc日誌的工具
文章轉自https://mp.weixin.qq.com/s?__biz=MzI2MzM3MzkyMg==&mid=2247485375&idx=1&sn=2ffb1e0413b96e92172ee0f27a7b3058
1、具有1-5工作經驗的,面對目前流行的技術不知從何下手,需要突破技術瓶頸的可以加群。
2、在公司待久了,過得很安逸,但跳槽時面試碰壁。需要在短時間內進修、跳槽拿高薪的可以加群。
3、如果沒有工作經驗,但基礎非常扎實,對java工作機制,常用設計思想,常用java開發框架掌握熟練的,可以加群。
4、覺得自己很牛B,一般需求都能搞定。但是所學的知識點沒有系統化,很難在技術領域繼續突破的可以加群。
5. 群號:高級架構群 647631030備註好資訊!
6.阿裡Java高級大牛直播講解知識點,分享知識,上面五大專題都是各位老師多年工作經驗的梳理和總結,帶著大家全面、科學地建立自己的技術體系和技術認知!
Java堆(Heap),是Java虛擬機器所管理的記憶體中最大的一塊。Java堆是被所有執行緒共用的一塊記憶體區域,在虛擬機器啟動時創建。此記憶體區域的唯一目的就是存放物件實例,幾乎所有的物件實例都在這裡分配記憶體。
方法區(Method Area),方法區(Method Area)與Java堆一樣,是各個執行緒共用的記憶體區域,它用於存儲已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的代碼等資料。
程式計數器(Program Counter Register),程式計數器(Program Counter Register)是一塊較小的記憶體空間,它的作用可以看做是當前執行緒所執行的位元組碼的行號指示器。
JVM棧(JVM Stacks),與程式計數器一樣,Java虛擬機器棧(Java Virtual Machine Stacks)也是執行緒私有的,它的生命週期與執行緒相同。虛擬機器棧描述的是Java方法執行的記憶體模型:每個方法被執行的時候都會同時創建一個棧幀(Stack Frame)用於存儲區域變數表、操作棧、動態連結、方法出口等資訊。每一個方法被調用直至執行完成的過程,就對應著一個棧幀在虛擬機器棧中從入棧到出棧的過程。
本地方法棧(Native Method Stacks),本地方法棧(Native Method Stacks)與虛擬機器棧所發揮的作用是非常相似的,其區別不過是虛擬機器棧為虛擬機器執行Java方法(也就是位元組碼)服務,而本地方法棧則是為虛擬機器使用到的Native方法服務。
物件分配規則
物件優先分配在Eden區,如果Eden區沒有足夠的空間時,虛擬機器執行一次Minor GC。
大物件直接進入老年代(大物件是指需要大量連續記憶體空間的物件)。這樣做的目的是避免在Eden區和兩個Survivor區之間發生大量的記憶體拷貝(新生代採用複製演算法收集記憶體)。
長期存活的物件進入老年代。虛擬機器為每個物件定義了一個年齡計數器,如果物件經過了1次Minor GC那麼物件會進入Survivor區,之後每經過一次Minor GC那麼對象的年齡加1,知道達到閥值對象進入老年區。
動態判斷物件的年齡。如果Survivor區中相同年齡的所有物件大小的總和大於Survivor空間的一半,年齡大於或等於該年齡的物件可以直接進入老年代。
空間分配擔保。每次進行Minor GC時,JVM會計算Survivor區移至老年區的物件的平均大小,如果這個值大於老年區的剩餘值大小則進行一次Full GC,如果小於檢查HandlePromotionFailure設置,如果true則只進行Monitor GC,如果false則進行Full GC。
GC演算法 垃圾回收
主要關注點:
物件存活判斷
GC演算法
垃圾回收器
物件存活判斷
判斷物件是否存活一般有兩種方式:
引用計數:每個物件有一個引用計數屬性,新增一個引用時計數加1,引用釋放時計數減1,計數為0時可以回收。此方法簡單,無法解決物件相互迴圈引用的問題。
可達性分析(Reachability Analysis):從GC Roots開始向下搜索,搜索所走過的路徑稱為引用鏈。當一個物件到GC Roots沒有任何引用鏈相連時,則證明此物件是不可用的,不可達對象。
GC演算法
GC最基礎的演算法有三種:標記 -清除演算法、複製演算法、標記-壓縮演算法,我們常用的垃圾回收器一般都採用分代收集演算法。
標記 -清除演算法,“標記-清除”(Mark-Sweep)演算法,如它的名字一樣,演算法分為“標記”和“清除”兩個階段:首先標記出所有需要回收的物件,在標記完成後統一回收掉所有被標記的物件。
複製演算法,“複製”(Copying)的收集演算法,它將可用記憶體按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當這一塊的記憶體用完了,就將還存活著的物件複製到另外一塊上面,然後再把已使用過的記憶體空間一次清理掉。
標記-壓縮演算法,標記過程仍然與“標記-清除”演算法一樣,但後續步驟不是直接對可回收物件進行清理,而是讓所有存活的物件都向一端移動,然後直接清理掉端邊界以外的記憶體
分代收集演算法,“分代收集”(Generational Collection)演算法,把Java堆分為新生代和老年代,這樣就可以根據各個年代的特點採用最適當的收集演算法。
1、具有1-5工作經驗的,面對目前流行的技術不知從何下手,需要突破技術瓶頸的可以加群。
2、在公司待久了,過得很安逸,但跳槽時面試碰壁。需要在短時間內進修、跳槽拿高薪的可以加群。
3、如果沒有工作經驗,但基礎非常扎實,對java工作機制,常用設計思想,常用java開發框架掌握熟練的,可以加群。
4、覺得自己很牛B,一般需求都能搞定。但是所學的知識點沒有系統化,很難在技術領域繼續突破的可以加群。
5. 群號:高級架構群 647631030備註好資訊!
6.阿裡Java高級大牛直播講解知識點,分享知識,上面五大專題都是各位老師多年工作經驗的梳理和總結,帶著大家全面、科學地建立自己的技術體系和技術認知!
垃圾回收器
Serial收集器,串列收集器是最古老,最穩定以及效率高的收集器,可能會產生較長的停頓,只使用一個執行緒去回收。
ParNew收集器,ParNew收集器其實就是Serial收集器的多執行緒版本。
Parallel收集器,Parallel Scavenge收集器類似ParNew收集器,Parallel收集器更關注系統的輸送量。
Parallel Old 收集器,Parallel Old是Parallel Scavenge收集器的老年代版本,使用多執行緒和“標記-整理”演算法
CMS收集器,CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器。
G1收集器,G1 (Garbage-First)是一款面向伺服器的垃圾收集器,主要針對配備多顆處理器及大容量記憶體的機器. 以極高概率滿足GC停頓時間要求的同時,還具備高輸送量性能特徵
GC分析 命令調優
主要關注點:
GC日誌分析
調優命令
調優工具
GC日誌分析
摘錄GC日誌一部分(前部分為年輕代gc回收;後部分為full gc回收):
2016-07-05T10:43:18.093+0800: 25.395: [GC [PSYoungGen: 274931K->10738K(274944K)] 371093K->147186K(450048K), 0.0668480 secs] [Times: user=0.17 sys=0.08, real=0.07 secs]2016-07-05T10:43:18.160+0800: 25.462: [Full GC [PSYoungGen: 10738K->0K(274944K)] [ParOldGen: 136447K->140379K(302592K)] 147186K->140379K(577536K) [PSPermGen: 85411K->85376K(171008K)], 0.6763541 secs] [Times: user=1.75 sys=0.02, real=0.68 secs]通過上面日誌分析得出,PSYoungGen、ParOldGen、PSPermGen屬於Parallel收集器。其中PSYoungGen表示gc回收前後年輕代的記憶體變化;ParOldGen表示gc回收前後老年代的記憶體變化;PSPermGen表示gc回收前後永久區的記憶體變化。young gc 主要是針對年輕代進行記憶體回收比較頻繁,耗時短;full gc 會對整個堆記憶體進行回城,耗時長,因此一般儘量減少full gc的次數
young gc 日誌:
Full GC日誌:
調優命令
Sun JDK監控和故障處理命令有jps jstat jmap jhat jstack jinfo
jps,JVM Process Status Tool,顯示指定系統內所有的HotSpot虛擬機器進程。
jstat,JVM statistics Monitoring是用於監視虛擬機器運行時狀態資訊的命令,它可以顯示出虛擬機器進程中的類裝載、記憶體、垃圾收集、JIT編譯等運行資料。
jmap,JVM Memory Map命令用於生成heap dump文件
jhat,JVM Heap Analysis Tool命令是與jmap搭配使用,用來分析jmap生成的dump,jhat內置了一個微型的HTTP/HTML伺服器,生成dump的分析結果後,可以在流覽器中查看
jstack,用於生成java虛擬機器當前時刻的執行緒快照。
jinfo,JVM Configuration info 這個命令作用是即時查看和調整虛擬機器運行參數。
調優工具
常用調優工具分為兩類,jdk自帶監控工具:jconsole和jvisualvm,協力廠商有:MAT(Memory Analyzer Tool)、GChisto。
jconsole,Java Monitoring and Management Console是從java5開始,在JDK中自帶的java監控和管理主控台,用於對JVM中記憶體,執行緒和類等的監控
jvisualvm,jdk自帶全能工具,可以分析記憶體快照、執行緒快照;監控記憶體變化、GC變化等。
MAT,Memory Analyzer Tool,一個基於Eclipse的記憶體分析工具,是一個快速、功能豐富的Java heap分析工具,它可以説明我們查找記憶體洩漏和減少記憶體消耗
GChisto,一款專業分析gc日誌的工具
文章轉自https://mp.weixin.qq.com/s?__biz=MzI2MzM3MzkyMg==&mid=2247485375&idx=1&sn=2ffb1e0413b96e92172ee0f27a7b3058
1、具有1-5工作經驗的,面對目前流行的技術不知從何下手,需要突破技術瓶頸的可以加群。
2、在公司待久了,過得很安逸,但跳槽時面試碰壁。需要在短時間內進修、跳槽拿高薪的可以加群。
3、如果沒有工作經驗,但基礎非常扎實,對java工作機制,常用設計思想,常用java開發框架掌握熟練的,可以加群。
4、覺得自己很牛B,一般需求都能搞定。但是所學的知識點沒有系統化,很難在技術領域繼續突破的可以加群。
5. 群號:高級架構群 647631030備註好資訊!
6.阿裡Java高級大牛直播講解知識點,分享知識,上面五大專題都是各位老師多年工作經驗的梳理和總結,帶著大家全面、科學地建立自己的技術體系和技術認知!