摘要:能夠讓的周期利用的更充分對(duì)于多線程應(yīng)用運(yùn)行在多處理器和多核系統(tǒng)上至很有挑戰(zhàn)性的。另外,當(dāng)達(dá)到飽和狀態(tài)的時(shí)候并不能說明的性能和伸縮性已經(jīng)達(dá)到了最佳的狀態(tài)。磁盤如果應(yīng)用有對(duì)磁盤進(jìn)行操作,我們需要對(duì)磁盤進(jìn)行監(jiān)控,來監(jiān)測(cè)可能出現(xiàn)的磁盤性能問題。
對(duì)于 Java 性能比較關(guān)心的同學(xué)大概都知道《Java Performance》這本書,一般而言,很多同學(xué)在日常寫 Java Code 的時(shí)候很少去關(guān)心性能問題,但是在我們寫 Code 的過程中必須考慮到性能對(duì)程序的影響。小到我們使用位運(yùn)算來實(shí)現(xiàn)算術(shù)運(yùn)算,大到我們對(duì) Java 代碼的總體架構(gòu)設(shè)計(jì),「性能」其實(shí)離我們很近。本篇文章主要提到幾個(gè)點(diǎn),希望能夠?qū)Υ蠹矣兴鶈l(fā)。
對(duì)于性能調(diào)優(yōu)而言,通常我們需要經(jīng)過以下三個(gè)步驟:1,性能監(jiān)控;2,性能剖析;3,性能調(diào)優(yōu)
作為國(guó)內(nèi)在技術(shù)層面遙遙領(lǐng)先的 APM 廠商,One APM 的 Ai 產(chǎn)品對(duì)于 Java Application 性能優(yōu)化提供了非常完善的指標(biāo):
性能監(jiān)控:
影響 Java 性能多維度指標(biāo)監(jiān)控
性能剖析:
Application 性能剖析
性能調(diào)優(yōu):通過分析影響Application性能問題根源,進(jìn)行優(yōu)化Application;
我們對(duì)于操作系統(tǒng)的性能關(guān)注主要在下面幾個(gè)點(diǎn)上:CPU 利用率、CPU 調(diào)度執(zhí)行隊(duì)列、內(nèi)存利用率、網(wǎng)絡(luò) I/O、磁盤I/O。
1.CPU 利用率
對(duì)于一個(gè)應(yīng)用來說,為了讓應(yīng)用達(dá)到最好的性能和可擴(kuò)展性,我們不僅僅要充分利用 CPU 周期內(nèi)可用的部分,而且要讓這部分 CPU 的使用更有價(jià)值,而不是浪費(fèi)。能夠讓 CPU 的周期利用的更充分對(duì)于多線程應(yīng)用運(yùn)行在多處理器和多核系統(tǒng)上至很有挑戰(zhàn)性的。另外,當(dāng) CPU 達(dá)到飽和狀態(tài)的時(shí)候并不能說明 CPU 的性能和伸縮性已經(jīng)達(dá)到了最佳的狀態(tài)。
為了區(qū)分應(yīng)用是如何利用 CPU 資源的,我們必須從操作系統(tǒng)級(jí)別來檢測(cè)。在很多操作系統(tǒng)上,CPU 的利用率統(tǒng)計(jì)報(bào)告通常包括用戶和系統(tǒng)或內(nèi)核對(duì)操作系統(tǒng)的使用。用戶對(duì) CPU 的使用是指應(yīng)用用來執(zhí)行應(yīng)用代碼執(zhí)行所需要的時(shí)間。相比之下,內(nèi)核和系統(tǒng)對(duì) CPU 的使用是指應(yīng)用用來執(zhí)行操作系統(tǒng)內(nèi)核代碼鎖花費(fèi)的時(shí)間。高的內(nèi)核或者系統(tǒng) CPU 使用率可以表明共享資源緊迫,或者是有大量的 I/O 設(shè)備交互。理想的狀態(tài)為了提高應(yīng)用的性能和伸縮性,讓內(nèi)核或系統(tǒng) CPU 時(shí)間為 0%,因?yàn)榛ㄔ趫?zhí)行內(nèi)核或系統(tǒng)代碼的時(shí)間是可以用來執(zhí)行應(yīng)用代碼的。因此 CPU 使用優(yōu)化的一個(gè)正確方向就是盡可能減少 CPU 花在執(zhí)行內(nèi)核代碼或者系統(tǒng)代碼上的時(shí)間。
對(duì)于計(jì)算密集型應(yīng)用,性能監(jiān)控比監(jiān)測(cè)用戶 CPU 使用和內(nèi)核或系統(tǒng) CPU 使用要更深層次,在計(jì)算密集型應(yīng)用中,我們需要監(jiān)測(cè) CPU 時(shí)鐘周期內(nèi)的執(zhí)行執(zhí)行條數(shù)(Instructions per clock;IPC),或者是每條 CPU 執(zhí)行所使用的CPU周期(cycles per instruction;CPI)。對(duì)于計(jì)算密集型應(yīng)用來說我們從這兩個(gè)維度來監(jiān)測(cè) CPU 是不錯(cuò)的選擇,因?yàn)楝F(xiàn)代操作系統(tǒng)的打包 CPU 性能報(bào)告工具通常只會(huì)打印 CPU 的利用率,而不會(huì)打印 CPU 周期內(nèi) CPU 用來執(zhí)行指令的時(shí)間。這意味著當(dāng) CPU 正在等待內(nèi)存中的數(shù)據(jù)的時(shí)候,操作系統(tǒng)CPU性能報(bào)告工具也會(huì)認(rèn)為 CPU 是正在使用的狀態(tài),我們把這個(gè)場(chǎng)景叫做「Stall」,這種場(chǎng)景經(jīng)常會(huì)發(fā)生,比如在 CPU 正在執(zhí)行指令的任何時(shí)候,只要是指令需要的數(shù)據(jù)沒有準(zhǔn)備好,也就是沒有在寄存器或者CPU緩存內(nèi),都會(huì)發(fā)生「Stall」場(chǎng)景。
當(dāng)「Stall」場(chǎng)景發(fā)生的時(shí)候 CPU 會(huì)浪費(fèi)時(shí)鐘周期,因?yàn)?CPU 必須要等待指令需要的數(shù)據(jù)到達(dá)寄存器或者緩沖器。而且在這個(gè)場(chǎng)景中,數(shù)百個(gè) CPU 時(shí)鐘周期被浪費(fèi)是很正常的事情,因此在計(jì)算密集型應(yīng)用中,提高性能的策略是減少「Stall」場(chǎng)景的發(fā)生或者是增強(qiáng) CPU 的緩存使用從而使得更少的 CPU 周期因?yàn)榈却龜?shù)據(jù)而浪費(fèi)掉。這類的性能監(jiān)控知識(shí)已經(jīng)超越了本書的內(nèi)容,需要性能專家的幫助了。然而,后面講到的 Oracle Solaris Studio Performance Analyzer 這種性能剖析工具將會(huì)包括此類數(shù)據(jù)。
2.CPU 調(diào)度隊(duì)列
除了對(duì) CPU 使用的監(jiān)控,我們也可以通過監(jiān)控 CPU 執(zhí)行隊(duì)列來檢查系統(tǒng)是否已經(jīng)滿負(fù)載。執(zhí)行隊(duì)列是用來存儲(chǔ)輕量級(jí)進(jìn)程,這些進(jìn)程通常是已經(jīng)準(zhǔn)備好執(zhí)行了但是正在等待 CPU 調(diào)度而在調(diào)度隊(duì)列等待的一種狀態(tài),當(dāng)輕量級(jí)進(jìn)程別當(dāng)前處理器能來得及處理的數(shù)量更多的時(shí)候,調(diào)度隊(duì)列將會(huì)產(chǎn)生。比較深的 CPU 調(diào)度隊(duì)列表明系統(tǒng)已經(jīng)滿負(fù)荷了。系統(tǒng)的執(zhí)行隊(duì)列深度等于虛擬處理器執(zhí)行不了的等待數(shù),虛擬處理器數(shù)等于系統(tǒng)的硬件線程數(shù)。我們可以用 JAVA 的 API 來拿到虛擬處理器數(shù)。
Runtime.avaliableProcessors()。當(dāng)執(zhí)行隊(duì)列深度大于虛擬處理器個(gè)數(shù)的四倍或更多的時(shí)候,操作系統(tǒng)將會(huì)出現(xiàn)反應(yīng)遲鈍的現(xiàn)象。
對(duì)于 CPU 調(diào)度隊(duì)列的檢測(cè)的一個(gè)通用指導(dǎo)是當(dāng)我們發(fā)現(xiàn)隊(duì)列深度高于虛擬進(jìn)程數(shù)一倍的時(shí)候就要注意了,但是沒有必要立即采取行動(dòng)。當(dāng)大于三倍或四倍或者更高的時(shí)候就要注意了,解決問題刻不容緩。
通常有兩個(gè)可選的途徑來觀察隊(duì)列的深度,第一個(gè)是通過增加 CPU 來分擔(dān)負(fù)載或者減少對(duì)現(xiàn)有 CPU 的負(fù)載。這種途徑從本質(zhì)上減少了每個(gè)執(zhí)行單元的負(fù)載線程數(shù),從而減少執(zhí)行執(zhí)行隊(duì)列的深度。
另外的一種途徑是通過剖析系統(tǒng)運(yùn)行的應(yīng)用來增加 CPU 的使用率,換個(gè)說法就是尋找一種可以減少花費(fèi)在垃圾回收上的 CPU 周期,或者尋找更好的算法來以更少的 CPU 周期來執(zhí)行 CPU 指令。性能專家通常專注后面的一種途徑:減少代碼的執(zhí)行路徑長(zhǎng)度和更好的 CPU 指令選擇。Java 程序員可以通過更好的執(zhí)行算法和數(shù)據(jù)結(jié)構(gòu)來提高代碼的執(zhí)行效率。
3.內(nèi)存利用率
其實(shí),除了 CPU 的使用率,系統(tǒng)的內(nèi)存屬性也需要被監(jiān)控,這些屬性包括比如:分頁(yè)、交換、鎖、多線程引起的上下文交換等。
交換通常發(fā)生在當(dāng)應(yīng)用需要的內(nèi)存大于實(shí)際的物理內(nèi)存的時(shí)候,處理這種情況操作系統(tǒng)通常會(huì)配置一個(gè)相應(yīng)的區(qū)域叫做交換區(qū)。交換區(qū)通常位于物理磁盤上,當(dāng)物理內(nèi)存內(nèi)應(yīng)用耗盡的時(shí)候,操作系統(tǒng)會(huì)將一部分內(nèi)存數(shù)據(jù)暫時(shí)交換到磁盤空間上,這部分內(nèi)存區(qū)域通常是訪問頻率最低的一塊區(qū)域,而不會(huì)影響比較「忙」的內(nèi)存區(qū)域;當(dāng)被交換到磁盤區(qū)域的內(nèi)存又被應(yīng)用訪問的時(shí)候,這個(gè)時(shí)候就需要從磁盤交換區(qū)將以頁(yè)為單位讀入內(nèi)存,交換會(huì)影響應(yīng)用的性能。
虛擬機(jī)的垃圾收集器在交換的時(shí)候性能非常差,因?yàn)槔占魉L問的大部分區(qū)域都是不可達(dá)的,也就是垃圾收集器會(huì)引起交換活動(dòng)的發(fā)生。場(chǎng)景是戲劇性的,如果垃圾收集的堆區(qū)域已經(jīng)被交換到了磁盤空間,這個(gè)時(shí)候?qū)?huì)以頁(yè)為單位發(fā)生交換,這樣才能夠被垃圾收集器所掃描到,在交換的過程中會(huì)戲劇性的引發(fā)垃圾收集器的收集時(shí)間延長(zhǎng),這個(gè)時(shí)候如果垃圾收集器是
「Stop The World」(使得應(yīng)用響應(yīng)停止)的,那么這個(gè)時(shí)間就會(huì)被延長(zhǎng)。
4.網(wǎng)絡(luò) I/O
分布式 Java 應(yīng)用的性能和伸縮性會(huì)受到網(wǎng)絡(luò)帶寬和網(wǎng)絡(luò)性能的限制。例如,如果我們往網(wǎng)絡(luò)接口發(fā)送比他能夠處理的更多的數(shù)據(jù)包,數(shù)據(jù)包將會(huì)堆積在操作系統(tǒng)的緩沖區(qū)內(nèi),這將會(huì)引發(fā)應(yīng)用延遲,另外其他的情況也會(huì)導(dǎo)致網(wǎng)絡(luò)應(yīng)用的延遲。
區(qū)分和監(jiān)控的工具通常在操作系統(tǒng)的打包工具中很難找到。盡管 Linux 提供了 Netstat 命令,Linux 和 Solaris 都提供了網(wǎng)絡(luò)使用情況的實(shí)現(xiàn),他們都提供了包括每秒發(fā)包、接包、錯(cuò)包、沖突等信息的統(tǒng)計(jì)。在以太網(wǎng)中,一小部分包沖突是很正常的現(xiàn)象。如果錯(cuò)包情況比較多那可能是網(wǎng)卡有問題了。同時(shí),盡管 netstat 可以統(tǒng)計(jì)網(wǎng)絡(luò)接口的發(fā)送和接收數(shù)據(jù)情況,這很難斷定網(wǎng)卡是否被充分利用。例如,如果 Netstat -i 顯示現(xiàn)在每秒有 2500 個(gè)包從網(wǎng)卡發(fā)出,但是我們?nèi)匀粺o(wú)法判斷當(dāng)前的網(wǎng)絡(luò)利用率是 100% 還是 1%,我們僅僅能夠知道目前有流量。這僅僅是在不知道網(wǎng)絡(luò)包大小的情況下能夠得到的結(jié)論。簡(jiǎn)單的說我們無(wú)法通過 Linux 和 Solaris 提供的 Netstat 來判斷當(dāng)前網(wǎng)絡(luò)是否影響了性能。我們需要一些其他的工具在我們的 Java 應(yīng)用運(yùn)行的過程中來監(jiān)測(cè)網(wǎng)絡(luò)。
5.磁盤 I/O
如果應(yīng)用有對(duì)磁盤進(jìn)行操作,我們需要對(duì)磁盤進(jìn)行監(jiān)控,來監(jiān)測(cè)可能出現(xiàn)的磁盤性能問題。一些應(yīng)用是 I/O 密集型的,比如數(shù)據(jù)庫(kù)。磁盤的使用通常還存在于應(yīng)用日志系統(tǒng),日志通常是我們用來記錄系統(tǒng)運(yùn)行過程中重要信息的。
OneAPM for Java 能夠深入到所有 Java 應(yīng)用內(nèi)部完成應(yīng)用性能管理和監(jiān)控,包括代碼級(jí)別性能問題的可見性、性能瓶頸的快速識(shí)別與追溯、真實(shí)用戶體驗(yàn)監(jiān)控、服務(wù)器監(jiān)控和端到端的應(yīng)用性能管理。想閱讀更多技術(shù)文章,請(qǐng)?jiān)L問 OneAPM 官方博客。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64682.html
摘要:在本文中我將會(huì)介紹應(yīng)用性能優(yōu)化的一般原則。性能優(yōu)化的流程圖摘取自和合著的性能,描述了應(yīng)用性能優(yōu)化的處理流程。例如,對(duì)每臺(tái)服務(wù)器,你面臨著為單個(gè)分配堆內(nèi)存和運(yùn)行個(gè)并為每個(gè)分配堆內(nèi)存的選擇。不過位能使用堆內(nèi)存最大理論值只有。 原文鏈接:http://www.cubrid.org/blog/dev-platform/the-principles-of-java-application-per...
摘要:調(diào)優(yōu)調(diào)優(yōu)中基于真實(shí)案例介紹了可用于調(diào)優(yōu)的最佳選項(xiàng)。的設(shè)置及其對(duì)的影響的設(shè)置及其對(duì)的影響中介紹了對(duì)選項(xiàng)在系統(tǒng)發(fā)生時(shí)對(duì)整體性能的影響。具體來說,我會(huì)介紹性能優(yōu)化的必要條件判斷是否需要優(yōu)化的步驟,同時(shí)也會(huì)列出在性能優(yōu)化過程中經(jīng)遇到的一些問題。 1. 理解Java垃圾回收 理解Java垃圾回收中我們學(xué)習(xí)了幾種不同的GC算法的處理過程,GC的工作方式,新生代與老年代的區(qū)別。所以,你應(yīng)該已經(jīng)了解...
摘要:對(duì)于大多數(shù)典型的企業(yè)應(yīng)用而言,其性能表現(xiàn)幾乎完全依賴于持久層的性能。速成法使用批處理對(duì)于批處理程序,驅(qū)動(dòng)程序提供了旨在減少網(wǎng)絡(luò)來回傳輸?shù)膬?yōu)化方法。速成法檢查錯(cuò)誤的提交間隔如果你使用批處理程序,提交間隔會(huì)對(duì)性能造成十倍甚至百倍的影響。 對(duì)于大多數(shù)典型的 Spring/Hibernate 企業(yè)應(yīng)用而言,其性能表現(xiàn)幾乎完全依賴于持久層的性能。此篇文章中將介紹如何確認(rèn)應(yīng)用是否受數(shù)據(jù)庫(kù)約束,同時(shí)...
摘要:導(dǎo)讀閱讀本文需要有足夠的時(shí)間,筆者會(huì)由淺到深帶你一步一步了解一個(gè)資深架構(gòu)師所要掌握的各類知識(shí)點(diǎn),你也可以按照文章中所列的知識(shí)體系對(duì)比自身,對(duì)自己進(jìn)行查漏補(bǔ)缺,覺得本文對(duì)你有幫助的話,可以點(diǎn)贊關(guān)注一下。目錄一基礎(chǔ)篇二進(jìn)階篇三高級(jí)篇四架構(gòu)篇五擴(kuò) 導(dǎo)讀:閱讀本文需要有足夠的時(shí)間,筆者會(huì)由淺到深帶你一步一步了解一個(gè)資深架構(gòu)師所要掌握的各類知識(shí)點(diǎn),你也可以按照文章中所列的知識(shí)體系對(duì)比自身,對(duì)自己...
閱讀 1219·2019-08-30 15:55
閱讀 964·2019-08-30 15:55
閱讀 2167·2019-08-30 15:44
閱讀 2898·2019-08-29 14:17
閱讀 1142·2019-08-29 12:45
閱讀 3319·2019-08-26 10:48
閱讀 3145·2019-08-23 18:18
閱讀 2615·2019-08-23 16:47