如何快速掌握Java的性能調優技巧

2020-12-25 電子發燒友

如何快速掌握Java的性能調優技巧

zhisheng的blog 發表於 2020-02-22 15:44:35

大多數開發者認為性能優化是一個複雜的話題,它需要大量的工作經驗和相關知識理論。好吧,這也不完全錯。

優化一個應用做到性能最優化可能不是件容易的任務,但是這並不意味著你沒有相關的知識就什麼也做不了。這裡有一些易於遵循的建議和最佳實踐可以幫助你創建一個性能良好的應用程式。

這些建議的大部分都是針對 Java 語言的。但是也有一些是跟語言無關的,你可以運用到任意的應用和程序中。在我們學習特定的 Java 編程性能調優之前,先來探討一些通用的技巧。

1. 在明確必要之前別急著優化

這可能是最重要的性能優化技巧之一。你應該遵循常見的最佳實踐做法並在案例中高效地應用它。但是這並不意味在證明必要之前,你應該更換任何標準庫或構建複雜的優化。

多數情況下,過早地優化會佔用大量的時間,而且會使代碼變得難以理解和閱讀。更糟糕的是,這些優化通常並沒帶來任何好處,因為你花了大量的時間在優化應用中的非關鍵部分。

那麼,要怎麼證明東西需要優化呢?

首先,你需要定義你的代碼速度得多快。例如,為所有 API 調用指定最大響應時間,或者指定在特定時間範圍內要導入的記錄數量。在做完這些後,你需要確定你應用中哪些部分太慢需要改進。當完成這些後,你就可以來看看第二個技巧提示。

2. 使用分析器找到真正的瓶頸

在完成第一部分的優化建議以鑑別出你應用中需要提升的部分後,要從哪裡入手呢?

你可以有兩種途徑來解決這個問題:

查看你的代碼,從看起來可疑的或者你覺得可能會導致出現問題的地方入手。

或者使用分析器獲取代碼每個部分的行為(執行過程)和性能的詳細信息。

希望我不需要解釋為什麼應該始終遵循第二種途徑/方法的原因。

很顯然,基於分析器的方式可以讓你更好地理解代碼的性能影響,並允許你去專注於更關鍵的部分(代碼)。即使你曾經使用過分析器,你一定記得你曾經多麼驚訝於一下就找到了代碼的哪些部分產生了性能問題。我第一次的猜測不止一次地導致我走錯了方向。

3. 為整個應用程式創建一個性能測試套件

這是另一個通用的可以幫助你避免在將性能改進部署到產品中之後經常會發生的許多意外問題的技巧。你應該總是定義一個性能測試套件來測試整個應用程式,並在性能改進之前和之後運行它。

這些額外的測試運行將幫助你識別你的改動所引起的功能和性能上的副作用,並確保不會導致弊大於利的更新。如果你處理的是被應用程式的多個不同部分使用的組件,如資料庫或緩存,那這一點尤為重要。

4. 優先關注最大瓶頸

在創建了測試套件並使用分析器分析你的應用程式之後,你可以列出一系列需要解決以提高性能的問題列表。這很好,但這並沒有回答你需要從哪裡開始的問題。你可以專注於速成方案,或從最重要的問題開始。

速成方案一開始可能會很有吸引力,因為你可以很快顯示第一個成果。但有時,可能有必要說服其他團隊成員或管理層認為性能分析是值得的。

一般來說,我建議從頂層開始,首先開始處理最重要的性能問題。這將為你提供最大的性能改進,而且你可能僅需要解決這些問題中的一小部分就能滿足你的性能要求。

常見的通用調優技巧到此結束。接下來讓我們仔細看看一些特定於 Java 的技巧。

5. 使用 StringBuilder 以編程方式連接字符串

在 Java 中有很多不同的選項來連接字符串。例如,你可以使用簡單的 + 或 + = ,以及老的 StringBuffer 或 StringBuilder 。

那麼,你應該選擇哪種方法呢?

答案取決於連接字符串的代碼。如果你是以編程方式將新內容添加到字符串中,例如在for循環中,則應使用 StringBuilder 。它很易於使用,並提供比 StringBuffer 更好的性能。但請記住,與 StringBuffer 相比, StringBuilder 不是線程安全的,可能並不適用於所有情況。

你只需要實例化一個新的 StringBuilder 並調用append方法來向String中添加一個新的部分。在你添加完了所有的部分後,你可以調用toString方法來檢索已連接的字符串。下面的代碼片段展示了一個簡單的例子。

在每次迭代期間,該循環將 i 轉換為一個 String ,並將其與空格一起添加到 StringBuilder sb 中。所以,最後,這段代碼在日誌文件中寫入 「This is a test0 1 2 3 4 5 6 7 8 9」 。

StringBuilder sb = new StringBuilder(「This is a test」);for (int i=0; i<10; i++) { sb.append(i); sb.append(」 「); } log.info(sb.toString);

正如你在代碼片段中看到的。我們可以為字符串的第一個元素提供到構造函數中。這會創建一個 StringBuilder ,其中包含了你所提供的字符串以及 16 個額外字符的容量。當你向 StringBuilder 中添加更多字符時,你的 JVM 將動態的增加 StringBuilder 的大小。

如果你已經知道字符串將包含多少個字符,則可以將該數字提供給不同的構造方法以實例化具有指定容量的 StringBuilder 。這進一步提高了效率,因為它不需要動態擴展其容量。

6. 儘可能使用基本類型

避免任何開銷並提高應用程式性能的另一種簡便快速的方法是使用基本類型而不是其包裝類。所以,最好使用 int 而不是 Integer ,是 double 而不是 Double 。這將使得你的 JVM 將值存儲在堆棧而不是堆中,以減少內存消耗,並更有效地處理它。

7. 儘量避免大整數和小數

由於我們已經在討論數據類型,所以我們也應該快速瀏覽大整數和小數。尤其是後者因其精確性而受歡迎。但這是有代價的。大整數和小數比一個簡單的 long 型或 double 型需要更多的內存,並會顯著減慢所有的運算。所以,如果你需要額外的精度,或者如果你的數字超出一個較長的範圍,最好要三思。這可能是你需要更改並解決性能問題的唯一方法,尤其是在實現數學算法時。

8. 使用 Apache Commons StringUtils.Replace 而不是 String.replace

一般來說,String.replace 方法可以正常工作,並且效率很高,尤其是在你使用 Java 9 的情況下。但是,如果你的應用程式需要大量的替換操作,並且沒有更新到最新的 Java 版本,那麼檢查更快和更有效的替代品依然是有必要的。

有一種候選方案是 Apache Commons Lang 的 StringUtils.replace 方法。正如 Lukas Eder 在他最近的一篇博客文章中所描述的,它遠遠勝過了 Java 8 的 String.replace 方法。

而且它只需要很小的改動。你只需要將 Apache Commons Lang 項目的 Maven 依賴項添加到你的應用程式的 pom.xml 中,並將 String.replacemethod 的所有調用替換為 StringUtils.replace 方法。

// replace this test.replace(「test」, 「simple test」); // with this StringUtils.replace(test, 「test」, 「simple test」);

9. 昂貴的緩存資源,如資料庫連接

緩存是避免重複執行昂貴或常用代碼片段的流行解決方案。總的思路很簡單:重複使用這些資源比創建一個新的資源更划算。

一個典型的例子是緩存池中的資料庫連接。新連接的創建需要時間,如果你重用現有連接,則可以避免這種情況。

你也可以在 Java 語言源碼中找到其他的例子。例如,在 Integer 類中的 valueOf 方法緩存了介於 -128 到 127 之間的值。你可能會說創建一個新的 Integer 並不是太昂貴,但是由於它經常被使用,因此緩存最常用的值也可以提供性能優勢。

但是,當你考慮使用緩存時,請記住緩存實現也會產生開銷。你需要花費額外的內存來儲存可重複使用的資源,因此你可能需要管理你的緩存以使資源可訪問,並刪除過期的資源。

所以,在開始緩存任何資源之前,請確保它們是經常使用的,以超過緩存實現的開銷(代價)。

總結

正如你所看到的,有時不需要太多的工作就可以提高你的應用程式的性能。本文中的大部分建議只需要稍作努力就可以將它們應用於你的代碼中。

但還是那句話,最重要的還是那些與是什麼程式語言無關的技巧:

在你知道其必要性之前不要進行優化

使用分析器(profiler)來查找真正的瓶

優先處理最大的瓶頸

打開APP閱讀更多精彩內容

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容圖片侵權或者其他問題,請聯繫本站作侵刪。 侵權投訴

相關焦點

  • 實用:9 個可以快速掌握的 Java 性能調優技巧
    優化一個應用做到性能最優化可能不是件容易的任務,但是這並不意味著你沒有相關的知識就什麼也做不了。這裡有一些易於遵循的建議和最佳實踐可以幫助你創建一個性能良好的應用程式。這些建議的大部分都是針對 Java 語言的。但是也有一些是跟語言無關的,你可以運用到任意的應用和程序中。在我們學習特定的 Java 編程性能調優之前,先來探討一些通用的技巧。1.
  • 實用,9 個可以快速掌握的 Java 性能調優技巧
    優化一個應用做到性能最優化可能不是件容易的任務,但是這並不意味著你沒有相關的知識就什麼也做不了。這裡有一些易於遵循的建議和最佳實踐可以幫助你創建一個性能良好的應用程式。這些建議的大部分都是針對 Java 語言的。但是也有一些是跟語言無關的,你可以運用到任意的應用和程序中。在我們學習特定的 Java 編程性能調優之前,先來探討一些通用的技巧。
  • 教學篇|11個簡單的Java性能調優技巧
    在討論專門針對Java的性能調優技巧之前,讓我們先來看看通用技巧。這可能是最重要的性能調整技巧之一。你應該遵循常見的最佳實踐做法並嘗試高效地實現用例。但是,這並不意味著在你證明必要之前,你應該更換任何標準庫或構建複雜的優化。在大多數情況下,過早優化不但會佔用大量時間,而且會使代碼變得難以閱讀和維護。
  • 11個簡單的Java性能調優技巧,傻瓜都能學會!
    優化應用程式以獲得最佳性能不是一件容易的事情。但是,這並不意味著如果你不具備這些知識,就不能做任何事情。這裡有11個易於遵循的建議和最佳實踐可以幫助你創建一個性能良好的應用程式。大部分建議是針對Java的。但也有若干建議是與語言無關的,可以應用於所有應用程式和程式語言。在討論專門針對Java的性能調優技巧之前,讓我們先來看看通用技巧。
  • Java 性能調優的 11 個實用技巧
    在討論專門針對Java的性能調優技巧之前,讓我們先來看看通用技巧。這可能是最重要的性能調整技巧之一。你應該遵循常見的最佳實踐做法並嘗試高效地實現用例。但是,這並不意味著在你證明必要之前,你應該更換任何標準庫或構建複雜的優化。在大多數情況下,過早優化不但會佔用大量時間,而且會使代碼變得難以閱讀和維護。更糟糕的是,這些優化通常不會帶來任何好處,因為你花費大量時間來優化的是應用程式的非關鍵部分。
  • 關於Java性能調優的11個簡單技巧
    也不是,以下就整理了11個實用技能,小夥伴們快來get吧~在你知道必要之前不要優化這可能是最重要的性能調整技巧之一。你應該遵循常見的最佳實踐做法並嘗試高效地實現用例。為整個應用程式創建性能測試套件這是另一個通用技巧,可以幫助你避免在將性能改進部署到生產後經常會發生的許多意外問題。
  • 大型企業JVM性能調優實戰Java垃圾收集器及gcroot
    02:JVM類加載機制大型企業JVM性能調優實戰之gcroot01:JVM類加載機制 - 類加載的生命周期概述java的class類文件實際上是二進位(字節碼)文件格式,class文件中包含了java虛擬機指令集和符號表以及若干其他輔助信息。
  • JVM性能調優實踐
    從入門到精通實戰課程分享1、JVM調優目標:使用較小的內存佔用來獲得較高的吞吐量或者較低的延遲。這裡有幾個比較重要的指標:當然,和CAP原則一樣,同時滿足一個程序內存佔用小、延遲低、高吞吐量是不可能的,程序的目標不同,調優時所考慮的方向也不同,在調優之前,必須要結合實際場景,有明確的的優化目標,找到性能瓶頸,對瓶頸有針對性的優化,最後進行測試,通過各種監控工具確認調優後的結果是否符合目標。
  • 作為一個Java 程式設計師 你應該會什麼
    ◆java.net 包下的60%以上的內容,對各個類的功能比較熟悉。◆java.text 包下的60%以上的內容,特別是各種格式化類。◆熟練運用JDBC. 8)、java.security 包下40%以上的內容,如果對於安全沒有接觸的話根本就不可能掌握java.
  • 譯文|RedHat 性能調優
    提交或回退確認潛在的性能問題調整優化參數回到 3 在我們開始前建立一個基準之前和之後的指標對於具體的指標,通過使用壓力測試程序,你可以快速建基準對於 apache 和 nginx,看看《在 apache 和 nginx 中進行日常日誌記錄工作》,這篇文章描述了如何將必要的量化指標數據記錄日誌。
  • SQL性能調優:查找慢查詢的5種方法
    我們來看看如何快速跟蹤它們,以便您可以處理這些查詢!SQL性能調優是一場永無止盡的鬥爭。我不是一名DBA,而是一名15年的開發人員。我從開始用SQL Server資料庫工作,一直到用Stackify的大SQL Azure資料庫。這麼多年來,我看到了一切。在本文中,我將提供一些技巧,以便開發人員可以在SQL Server中查找SQL慢查詢並進行性能調優。
  • java如何快速入門?
    java如何快速入門正確掌握Java的基本知識由於Java為開發人員提供了如此多的特性和選項,人們有時會被分散注意力在太短的時間內學習了太多的東西java如何快速入門真正弄懂你敲出的代碼是做什麼的只要你理解了代碼背後的思想,算法和整個編譯過程就會顯得非常有意義。
  • JAVA架構師必備詞彙和知識點
    kafka的數據傳輸事務性及實踐練習07、分布式緩存分析對比memcache的原理分析及使用memcache和redis的橫向對比分析分布式接口技術webservice/RMI/restful的使用09、高並發專題-資料庫層面優化分庫分表的原理及規則講解資料庫主備及高可用10、性能調優專題
  • JVM調優參數、方法、工具以及案例總結
    主要圍繞四個大的方面展開,分別是JVM調優參數、JVM調優方法(流程)、JVM調優工具、JVM調優案例,調優案例目前正在分析,會在將來補上。-XX:+PrintFlagsInitial 默認參數值java -XX:+PrintFlagsFinal 最終參數值java -XX:+PrintFlagsFinal | grep xxx 找到對應的參數java -XX:+PrintFlagsFinal -version |grep GCJVM調優流程JVM調優,設計到三個大的方面,在伺服器出現問題之前要先根據業務場景選擇合適的垃圾處理器
  • 5款強大的JVM 性能調優監控工具 !
    本文將對一些常用的JVM性能調優監控工具進行介紹,希望能起拋磚引玉之用。一、 jps(Java Virtual Machine Process Status Tool)      :基礎工具   jps主要用來輸出JVM中運行的進程狀態信息。語法格式如下:如果不指定hostid就默認為當前主機或伺服器。
  • GC算法 + 垃圾收集器 + 性能調優實戰
    一般將java堆分為新生代和老年代,這樣我們就可以根據各個年代的特點選擇合適的垃圾收集算法。在新生代中,每次收集都有大量對象死去,所以可以選擇複製算法,只要付出少量對象的複製成本就可以完成每次垃圾收集。而老年代的對象存活機率時比較高的,而且沒有額外的空間對它進行分配擔保,就必須選擇「標記-清除」或者「標記-整理」算法進行垃圾收集。
  • 給Java新手的一些建議——Java知識點歸納(Java基礎部分)
    在JVM這個大類中,我認為需要掌握的知識有:JVM內存模型和結構GC原理,性能調優調優:Thread Dump, 分析內存結構class 二進位字節碼結構, class loader 體系 , class加載過程 , 實例創建過程方法執行過程Java各個大版本更新提供的新特性(需要簡單了解)
  • 通向架構師的道路(第四天)之 Tomcat 性能調優
    (點擊上方公眾號,可快速關注)來源:袁鳴凱,blog.csdn.net/lifetragedy/article/details
  • HBase調優|HBase + G1GC 性能調優
    先傳送門一下,之前在HBaseConAsia2017分享過一個G1GC調優的PPT: http://openinx.github.io/2012/01/01/my-share/首先,對G1算法不熟悉的同學,可以仔細讀一讀Oracle的G1算法教程,教程基本交代了G1的運行原理以及和CMS本質區別,如果對算法細節感興趣,可以讀一下Garbage-First
  • java垃圾回收以及jvm參數調優概述
    本文從基礎的理論入手,結合作者在實際項目中的實際使用來闡述JVM的垃圾回收機制以及如何對JVM進行調優。建議可以保存下來慢慢看,或者找一段安靜的時間全片通讀。關於作者,想必solr中國的小夥伴都不會陌生,這這裡就不做過多的介紹了。本文共分為五個部分,詳細闡述JAVA的垃圾回收以及JVM的參數調優。