天天看點

2020年薪30W的Java程式員都要求熟悉JVM與性能調優!前言一、JVM 記憶體區域劃分二、JVM 執行子系統三.垃圾回收器和記憶體配置設定政策四、編寫高效優雅 Java 程式五、性能優化最後

前言

作為Java程式員,你有沒有被JVM傷害過?面試的時候是否碰到過對JVM的靈魂拷問?

2020年薪30W的Java程式員都要求熟悉JVM與性能調優!前言一、JVM 記憶體區域劃分二、JVM 執行子系統三.垃圾回收器和記憶體配置設定政策四、編寫高效優雅 Java 程式五、性能優化最後

一、JVM 記憶體區域劃分

1.程式計數器(線程私有)

程式計數器(Program Counter Register),也有稱作為 PC 寄存器。儲存的是程式目前執行的指令的位址(也可以說儲存下一條指令的所在存儲單元的位址),當 CPU 需要執行指令時,需要從程式計數器中得到目前需要執行的指令所在存儲單元的位址,然後根據得到的位址擷取到指令,在得到指令之後,程式計數器便自動加 1 或者根據轉移指針得到下一條指令的位址,如此循環,直至執行完所有的指令。也就是說是用來訓示執行哪條指令的。

由于在 JVM 中,多線程是通過線程輪流切換來獲得 CPU 執行時間的,是以,在任一具體時刻,一個 CPU 的核心隻會執行一條線程中的指令,是以,為了能夠使得每個線程都線上程切換後能夠恢複在切換之前的程式執行位置,每個線程都需要有自己獨立的程式計數器,并且不能互相被幹擾,否則就會影響到程式的正常執行次序。是以,可以這麼說,程式計數器是每個線程所私有的。

在 JVM 規範中規定,如果線程執行的是非 native 方法,則程式計數器中儲存的是目前需要執行的指令的位址;如果線程執行的是 native 方法,則程式計數器中的值是 undefined。

由于程式計數器中存儲的資料所占空間的大小不會随程式的執行而發生改變,是以,對于程式計數器是不會發生記憶體溢出現象(OutOfMemory)的。

異常情況:

不存在

2.Java 棧(線程私有)

3.本地方法棧(線程私有)

4.堆(線程共享)

5.方法區(線程共享)

6.直接記憶體(線程共享)

2020年薪30W的Java程式員都要求熟悉JVM與性能調優!前言一、JVM 記憶體區域劃分二、JVM 執行子系統三.垃圾回收器和記憶體配置設定政策四、編寫高效優雅 Java 程式五、性能優化最後

二、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 語言結構體的僞結構來存儲資料,這種僞結構中隻有兩種資料類型:無符号數和表。

無符号數屬于基本的資料類型,以 u1、u2、u4、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 方法調用指令

2020年薪30W的Java程式員都要求熟悉JVM與性能調優!前言一、JVM 記憶體區域劃分二、JVM 執行子系統三.垃圾回收器和記憶體配置設定政策四、編寫高效優雅 Java 程式五、性能優化最後

2.12 方法傳回指令

2.13 異常處理指令

2.14 同步指令

3.類加載機制

4.類加載器

4.1 系統的類加載器

4.2 雙親委派模型

5.Tomcat 類加載機制

6.方法調用詳解

6.1 解析

6.2 靜态分派

6.3 動态分派

6.4 基于棧的位元組碼解釋執行引擎

2020年薪30W的Java程式員都要求熟悉JVM與性能調優!前言一、JVM 記憶體區域劃分二、JVM 執行子系統三.垃圾回收器和記憶體配置設定政策四、編寫高效優雅 Java 程式五、性能優化最後

三.垃圾回收器和記憶體配置設定政策

1.Java 中是值傳遞還是引用傳遞?

2.引用類型

3.基本垃圾回收算法

3.1.1 引用計數(Reference Counting):

比較古老的回收算法。原理是此對象有一個引用,即增加一個計數,删除一個引用則減少一個計數。垃圾回收時,隻用收集計數為 0 的對象。此算法最緻命的是無法處理循環引用的問題。

3.1.2 可達性分析清理

2020年薪30W的Java程式員都要求熟悉JVM與性能調優!前言一、JVM 記憶體區域劃分二、JVM 執行子系統三.垃圾回收器和記憶體配置設定政策四、編寫高效優雅 Java 程式五、性能優化最後

标記-清除(Mark-Sweep):此算法執行分兩階段。第一階段從引用根節點開始标記所有被引用的對象,第二階段周遊整個堆,把未标記的對象清除。此算法需要暫停整個應用,同時,會産生記憶體碎片。

2020年薪30W的Java程式員都要求熟悉JVM與性能調優!前言一、JVM 記憶體區域劃分二、JVM 執行子系統三.垃圾回收器和記憶體配置設定政策四、編寫高效優雅 Java 程式五、性能優化最後

複制(Copying): 此算法把記憶體空間劃為兩個相等的區域,每次隻使用其中一個區域。垃圾回收時,周遊目前使用區域,把正在使用中的對象複制到另外一個區域中。次算法每次隻處理正在使用中的對象,是以複制成本比較小,同時複制過去以後還能進行相應的記憶體整理,不會出現“碎片”問題。當然,此算法的缺點也是很明顯的,就是需要兩倍記憶體空間。

2020年薪30W的Java程式員都要求熟悉JVM與性能調優!前言一、JVM 記憶體區域劃分二、JVM 執行子系統三.垃圾回收器和記憶體配置設定政策四、編寫高效優雅 Java 程式五、性能優化最後

标記-整理(Mark-Compact):此算法結合了“标記-清除”和“複制”兩個算法的優點。也是分兩階段,第一階段從根節點開始标記所有被引用對象,第二階段周遊整個堆,清除标記對象,并未标記對象并且把存活對象“壓縮”到堆的其中一塊,按順序排放。此算法避免了“标記-清除”的碎片問題,同時也避免了“複制”算法的空間問題。

3.1 按照基本回收政策分

3.2 按分區對待的方式分

3.3 按系統線程分

4.分代處理垃圾

5.JAVA 中垃圾回收 GC 的類型

2020年薪30W的Java程式員都要求熟悉JVM與性能調優!前言一、JVM 記憶體區域劃分二、JVM 執行子系統三.垃圾回收器和記憶體配置設定政策四、編寫高效優雅 Java 程式五、性能優化最後

四、編寫高效優雅 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.通用程式設計

2020年薪30W的Java程式員都要求熟悉JVM與性能調優!前言一、JVM 記憶體區域劃分二、JVM 執行子系統三.垃圾回收器和記憶體配置設定政策四、編寫高效優雅 Java 程式五、性能優化最後

五、性能優化

一個 web 應用不是一個孤立的個體,它是一個系統的部分,系統中的每一部分都會影響整

個系統的性能

1.常用的性能評價/測試名額

1.1 響應時間

送出請求和傳回該請求的響應之間使用的時間,一般比較關注平均響應時間。

常用操作的響應時間清單:

2020年薪30W的Java程式員都要求熟悉JVM與性能調優!前言一、JVM 記憶體區域劃分二、JVM 執行子系統三.垃圾回收器和記憶體配置設定政策四、編寫高效優雅 Java 程式五、性能優化最後

1.2 并發數

同一時刻,對伺服器有實際互動的請求數。

和網站線上使用者數的關聯:1000 個同時線上使用者數,可以估計并發數在 5%到 15%之間,也就是同時并發數在 50~150 之間。

1.3 吞吐量

對機關時間内完成的工作量(請求)的量度

1.4 關系

系統吞吐量和系統并發數以及響應時間的關系:

了解為高速公路的通行狀況:

吞吐量是每天通過收費站的車輛數目(可以換算成收費站收取的高速費),并發數是高速公路上的正在行駛的車輛數目,響應時間是車速。車輛很少時,車速很快。但是收到的高速費也相應較少;

随着高速公路上車輛數目的增多,車速略受影響,但是收到的高速費增加很快;

随着車輛的繼續增加,車速變得越來越慢,高速公路越來越堵,收費不增反降;

如果車流量繼續增加,超過某個極限後,任務偶然因素都會導緻高速全部癱瘓,車走不動,當然後也收不着,而高速公路成了停車場(資源耗盡)。

2.常用的性能優化手段

2.1 避免過早優化

2.2 進行系統性能測試

2.3 尋找系統瓶頸,分而治之,逐漸優化

2.4 前端優化常用手段

2020年薪30W的Java程式員都要求熟悉JVM與性能調優!前言一、JVM 記憶體區域劃分二、JVM 執行子系統三.垃圾回收器和記憶體配置設定政策四、編寫高效優雅 Java 程式五、性能優化最後

3 應用服務性能優化

3.1 緩存

3.1.1 緩存的基本原理和本質

3.1.2 合理使用緩沖的準則

3.1.3 分布式緩存與一緻性哈希

3.2 異步

3.2.1 同步和異步,阻塞和非阻塞

3.2.2 常見異步的手段

3.3 叢集

2020年薪30W的Java程式員都要求熟悉JVM與性能調優!前言一、JVM 記憶體區域劃分二、JVM 執行子系統三.垃圾回收器和記憶體配置設定政策四、編寫高效優雅 Java 程式五、性能優化最後

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文檔,歡迎關注我的公種浩:程式員追風,擷取這些整理的資料!

希望能幫助到你面試前的複習且找到一個好的工作,也節省大家在網上搜尋資料的時間來學習。

最後

歡迎大家一起交流,喜歡文章記得關注我點個贊喲,感謝支援!