前言前端
做爲Java程序員,你有沒有被JVM傷害過?面試的時候是否碰到過對JVM的靈魂拷問?程序員
1、JVM 內存區域劃分web
1.程序計數器(線程私有)面試
程序計數器(Program Counter Register),也有稱做爲 PC 寄存器。保存的是程序當前執行的指令的地址(也能夠說保存下一條指令的所在存儲單元的地址),當 CPU 須要執行指令時,須要從程序計數器中獲得當前須要執行的指令所在存儲單元的地址,而後根據獲得的地址獲取到指令,在獲得指令以後,程序計數器便自動加 1 或者根據轉移指針獲得下一條指令的地址,如此循環,直至執行完全部的指令。也就是說是用來指示執行哪條指令的。算法
因爲在 JVM 中,多線程是經過線程輪流切換來得到 CPU 執行時間的,所以,在任一具體時刻,一個 CPU 的內核只會執行一條線程中的指令,所以,爲了可以使得每一個線程都在線程切換後可以恢復在切換以前的程序執行位置,每一個線程都須要有本身獨立的程序計數器,而且不能互相被幹擾,不然就會影響到程序的正常執行次序。所以,能夠這麼說,程序計數器是每一個線程所私有的。編程
在 JVM 規範中規定,若是線程執行的是非 native 方法,則程序計數器中保存的是當前須要執行的指令的地址;若是線程執行的是 native 方法,則程序計數器中的值是 undefined。數組
因爲程序計數器中存儲的數據所佔空間的大小不會隨程序的執行而發生改變,所以,對於程序計數器是不會發生內存溢出現象(OutOfMemory)的。緩存
異常狀況:性能優化
不存在服務器
2.Java 棧(線程私有)
3.本地方法棧(線程私有)
4.堆(線程共享)
5.方法區(線程共享)
6.直接內存(線程共享)
2、JVM 執行子系統
1.Class 類文件結構
1.1 Java 跨平臺的基礎
各類不一樣平臺的虛擬機與全部平臺都統一使用的程序存儲格式——字節碼(ByteCode)是構成平臺無關性的基石,也是語言無關性的基礎。Java 虛擬機不和包括 Java 在內的任何語言綁定,它只與「Class 文件」這種特定的二進制文件格式所關聯,Class 文件中包含了 Java虛擬機指令集和符號表以及若干其餘輔助信息。
1.2 Class 類的本質
任何一個 Class 文件都對應着惟一一個類或接口的定義信息,但反過來講,Class 文件實際上它並不必定以磁盤文件的形式存在。Class 文件是一組以 8 位字節爲基礎單位的二進制流。
1.3 Class 文件格式
各個數據項目嚴格按照順序緊湊地排列在 Class 文件之中,中間沒有添加任何分隔符,這使得整個 Class 文件中存儲的內容幾乎所有是程序運行的必要數據,沒有空隙存在。Class 文件格式採用一種相似於 C 語言結構體的僞結構來存儲數據,這種僞結構中只有兩種數據類型:無符號數和表。
無符號數屬於基本的數據類型,以 u一、u二、u四、u8 來分別表明 1 個字節、2 個字節、4 個字節和 8 個字節的無符號數,無符號數能夠用來描述數字、索引引用、數量值或者按照 UTF-8編碼構成字符串值。
表是由多個無符號數或者其餘表做爲數據項構成的複合數據類型,全部表都習慣性地以「_info」結尾。表用於描述有層次關係的複合結構的數據,整個 Class 文件本質上就是一張表。
2.字節碼指令
2.1 加載和存儲指令
2.2 運算或算術指令
2.3 類型轉換指令
2.4 建立類實例的指令
2.5 建立數組的指令
2.6 訪問字段指令
2.7 數組存取相關指令
2.8 檢查類實例類型的指令
2.9 操做數棧管理指令
2.10 控制轉移指令
2.11 方法調用指令
2.12 方法返回指令
2.13 異常處理指令
2.14 同步指令
3.類加載機制
4.類加載器
4.1 系統的類加載器
4.2 雙親委派模型
5.Tomcat 類加載機制
6.方法調用詳解
6.1 解析
6.2 靜態分派
6.3 動態分派
6.4 基於棧的字節碼解釋執行引擎
三.垃圾回收器和內存分配策略
1.Java 中是值傳遞仍是引用傳遞?
2.引用類型
3.基本垃圾回收算法
3.1.1 引用計數(Reference Counting):
比較古老的回收算法。原理是此對象有一個引用,即增長一個計數,刪除一個引用則減小一個計數。垃圾回收時,只用收集計數爲 0 的對象。此算法最致命的是沒法處理循環引用的問題。
3.1.2 可達性分析清理
標記-清除(Mark-Sweep):此算法執行分兩階段。第一階段從引用根節點開始標記全部被引用的對象,第二階段遍歷整個堆,把未標記的對象清除。此算法須要暫停整個應用,同時,會產生內存碎片。
複製(Copying): 此算法把內存空間劃爲兩個相等的區域,每次只使用其中一個區域。垃圾回收時,遍歷當前使用區域,把正在使用中的對象複製到另一個區域中。次算法每次只處理正在使用中的對象,所以複製成本比較小,同時複製過去之後還能進行相應的內存整理,不會出現「碎片」問題。固然,此算法的缺點也是很明顯的,就是須要兩倍內存空間。
標記-整理(Mark-Compact):此算法結合了「標記-清除」和「複製」兩個算法的優勢。也是分兩階段,第一階段從根節點開始標記全部被引用對象,第二階段遍歷整個堆,清除標記對象,並未標記對象而且把存活對象「壓縮」到堆的其中一塊,按順序排放。此算法避免了「標記-清除」的碎片問題,同時也避免了「複製」算法的空間問題。
3.1 按照基本回收策略分
3.2 按分區對待的方式分
3.3 按系統線程分
4.分代處理垃圾
5.JAVA 中垃圾回收 GC 的類型
4、編寫高效優雅 Java 程序
1.面向對象
1.1 構造器參數太多怎麼辦?
用 builder 模式,用在
(1)5 個或者 5 個以上的成員變量
(2)參數很少,可是在將來,參數會增長
Builder 模式:
屬於對象的建立模式,通常有
(1)抽象建造者:通常來講是個接口,包含
1)建造方法,建造部件的方法(不止一個)
2)返回產品的方法
(2) 具體建造者
(3) 導演者,調用具體的建造者,建立產品對象
(4)產品,須要建造的複雜對象
對於客戶端,建立導演者和具體建造者,並把具體建造者交給導演者,而後由客戶端通知導演者操縱建造者進行產品的建立。
在實際的應用過程當中,有時會省略抽象建造者和導演者。
1.2 不須要實例化的類應該構造器私有
1.3 不要建立沒必要要的對象
1.4 避免使用終結方法
1.5 使類和成員的可訪問性最小化
1.6 使可變性最小化
1.7 複合優先於繼承
1.8 接口優於抽象類
2.方法
2.1 可變參數要謹慎使用
2.2 返回零長度的數組或集合,不要返回 null
2.3 優先使用標準的異常
3.通用程序設計
5、性能優化
一個 web 應用不是一個孤立的個體,它是一個系統的部分,系統中的每一部分都會影響整
個系統的性能
1.經常使用的性能評價/測試指標
1.1 響應時間
提交請求和返回該請求的響應之間使用的時間,通常比較關注平均響應時間。
經常使用操做的響應時間列表:
1.2 併發數
同一時刻,對服務器有實際交互的請求數。
和網站在線用戶數的關聯:1000 個同時在線用戶數,能夠估計併發數在 5%到 15%之間,也就是同時併發數在 50~150 之間。
1.3 吞吐量
對單位時間內完成的工做量(請求)的量度
1.4 關係
系統吞吐量和系統併發數以及響應時間的關係:
理解爲高速公路的通行情況:
吞吐量是天天經過收費站的車輛數目(能夠換算成收費站收取的高速費),併發數是高速公路上的正在行駛的車輛數目,響應時間是車速。車輛不多時,車速很快。可是收到的高速費也相應較少;
隨着高速公路上車輛數目的增多,車速略受影響,可是收到的高速費增長很快;
隨着車輛的繼續增長,車速變得愈來愈慢,高速公路愈來愈堵,收費不增反降;
若是車流量繼續增長,超過某個極限後,任務偶然因素都會致使高速所有癱瘓,車走不動,固然後也收不着,而高速公路成了停車場(資源耗盡)。
2.經常使用的性能優化手段
2.1 避免過早優化
2.2 進行系統性能測試
2.3 尋找系統瓶頸,分而治之,逐步優化
2.4 前端優化經常使用手段
3 應用服務性能優化
3.1 緩存
3.1.1 緩存的基本原理和本質
3.1.2 合理使用緩衝的準則
3.1.3 分佈式緩存與一致性哈希
3.2 異步
3.2.1 同步和異步,阻塞和非阻塞
3.2.2 常見異步的手段
3.3 集羣
3.4 應用相關
3.4.1 代碼級別
3.4.2 併發編程
3.4.3 資源的複用
3.4.4 JVM
3.4.5 GC 調優
3.4.6 調優實戰
3.4.7 存儲性能優化
上面的這些問題只是給你們一個借鑑做用,最主要的是給本身增長知識的儲備,有備無患。
關於JVM與性能調優總結了將近50頁pdf文檔,歡迎關注個人公種浩:程序員追風,獲取這些整理的資料!
但願能幫助到你面試前的複習且找到一個好的工做,也節省你們在網上搜索資料的時間來學習。
最後
歡迎你們一塊兒交流,喜歡文章記得關注我點個贊喲,感謝支持!