- 適用於 JDK 23 的 GraalVM(最新)
- 適用於 JDK 24 的 GraalVM(搶先體驗)
- 適用於 JDK 21 的 GraalVM
- 適用於 JDK 17 的 GraalVM
- 封存
- 開發版本
分析命令列工具
GraalVM 的分析命令列工具可協助您透過分析 CPU 和記憶體使用率來最佳化程式碼。
大多數應用程式在 20% 的程式碼中花費 80% 的執行時間。因此,為了最佳化程式碼,必須了解應用程式將時間花費在哪裡。在本節中,我們將使用範例應用程式來示範 GraalVM 提供的三個主要分析功能:CPU 追蹤器、CPU 取樣器和記憶體追蹤器。
此範例應用程式使用基於埃拉托斯特尼篩法演算法的基本質數計算器。
-
將下列程式碼複製到名為
primes.js
的新檔案中class AcceptFilter { accept(n) { return true } } class DivisibleByFilter { constructor(number, next) { this.number = number; this.next = next; } accept(n) { var filter = this; while (filter != null) { if (n % filter.number === 0) { return false; } filter = filter.next; } return true; } } class Primes { constructor() { this.number = 2; this.filter = new AcceptFilter(); } next() { while (!this.filter.accept(this.number)) { this.number++; } this.filter = new DivisibleByFilter(this.number, this.filter); return this.number; } } var primes = new Primes(); var primesArray = []; for (let i = 0; i < 5000; i++) { primesArray.push(primes.next()); } console.log(`Computed ${primesArray.length} prime numbers. ` + `The last 5 are ${primesArray.slice(-5)}.`);
- 執行
js primes.js
。範例應用程式應列印如下輸出js primes.js Computed 5000 prime numbers. The last 5 are 48563,48571,48589,48593,48611.
此程式需要一些時間來計算。接下來,您將檢查時間花費在哪裡。
- 執行
js --cpusampler primes.js
以啟用 CPU 取樣。CPU 取樣器應列印範例應用程式的如下輸出js --cpusampler primes.js Computed 5000 prime numbers. The last 5 are 48563,48571,48589,48593,48611. ---------------------------------------------------------------------------------------------- Sampling Histogram. Recorded 250 samples with period 10ms. Self Time: Time spent on the top of the stack. Total Time: Time spent somewhere on the stack. ---------------------------------------------------------------------------------------------- Thread[main,5,main] Name || Total Time || Self Time || Location ---------------------------------------------------------------------------------------------- accept || 2150ms 86.0% || 2150ms 86.0% || primes.js~13-22:191-419 next || 2470ms 98.8% || 320ms 12.8% || primes.js~31-37:537-737 :program || 2500ms 100.0% || 30ms 1.2% || primes.js~1-46:0-982 ----------------------------------------------------------------------------------------------
依預設,取樣器會為每個 JavaScript 函式列印執行時間長條圖。
您可以使用
--cpusampler=flamegraph
選項要求以 SVG 格式產生火焰圖js --cpusampler=flamegraph primes.js
它應該產生一個名為
flamegraph.svg
的檔案,其中包含如下內容您可以透過按一下元素來放大圖表。
依預設,CPU 取樣會每 10 毫秒取樣一次。從結果中,我們可以看到大約 89% 的時間花費在
DivisibleByFilter.accept
函式中。accept(n) { var filter = this; while (filter != null) { if (n % filter.number === 0) { return false; } filter = filter.next; } return true; }
如需詳細資訊,請參閱這篇部落格文章。
現在使用 CPU 追蹤器來收集每個陳述式的執行計數
- 執行
js primes.js --cputracer --cputracer.TraceStatements --cputracer.FilterRootName=*accept
以收集結尾為accept
的方法中所有陳述式的執行計數js primes.js --cputracer --cputracer.TraceStatements --cputracer.FilterRootName=accept Computed 5000 prime numbers. The last 5 are 48563,48571,48589,48593,48611. ----------------------------------------------------------------------------------------- Tracing Histogram. Counted a total of 468336895 element executions. Total Count: Number of times the element was executed and percentage of total executions. Interpreted Count: Number of times the element was interpreted and percentage of total executions of this element. Compiled Count: Number of times the compiled element was executed and percentage of total executions of this element. ----------------------------------------------------------------------------------------- Name | Total Count | Interpreted Count | Compiled Count | Location ----------------------------------------------------------------------------------------- accept | 234117338 50.0% | 365660 0.2% | 233751678 99.8% | primes.js~15:245-258 accept | 117053670 25.0% | 182582 0.2% | 116871088 99.8% | primes.js~16-18:275-348 accept | 117005061 25.0% | 181001 0.2% | 116824060 99.8% | primes.js~19:362-381 accept | 53608 0.0% | 1829 3.4% | 51779 96.6% | primes.js~14:211-227 accept | 53608 0.0% | 1829 3.4% | 51779 96.6% | primes.js~13-22:191-419 accept | 48609 0.0% | 1581 3.3% | 47028 96.7% | primes.js~17:322-334 accept | 4999 0.0% | 248 5.0% | 4751 95.0% | primes.js~21:402-413 accept | 1 0.0% | 1 100.0% | 0 0.0% | primes.js~2-4:25-61 accept | 1 0.0% | 1 100.0% | 0 0.0% | primes.js~3:45-55 -----------------------------------------------------------------------------------------
輸出顯示每個陳述式的執行計數器,而不是計時資訊。追蹤長條圖通常可深入了解需要最佳化的演算法的行為。
- 執行
js primes.js --experimental-options --memtracer
以顯示原始程式碼位置和已報告配置的計數。請注意,用於擷取配置的記憶體追蹤器工具目前是 GraalVM 中的實驗性功能。因此,--memtracer
必須以--experimental-options
命令列選項作為前綴。js primes.js --experimental-options --memtracer Computed 5000 prime numbers. The last 5 are 48563,48571,48589,48593,48611. ------------------------------------------------------------ Location Histogram with Allocation Counts. Recorded a total of 5007 allocations. Total Count: Number of allocations during the execution of this element. Self Count: Number of allocations in this element alone (excluding sub calls). -------------------------------------------------------- Name | Self Count | Total Count | Location -------------------------------------------------------- next | 5000 99.9% | 5000 99.9% | primes.js~31-37:537-737 :program | 6 0.1% | 5007 100.0% | primes.js~1-46:0-982 Primes | 1 0.0% | 1 0.0% | primes.js~25-38:424-739 --------------------------------------------------------
此輸出顯示每個函式記錄的配置數量。對於計算的每個質數,程式會在
DivisibleByFilter
的next
中配置一個物件,並在constructor
中配置一個物件。配置的記錄與編譯器是否可以消除它們無關。GraalVM 編譯器在最佳化配置方面特別強大,並且可以將配置推送到不常發生的分支中,以提高執行效能。GraalVM 團隊計劃未來將有關記憶體最佳化的資訊新增至記憶體追蹤器中。
工具選項 #
在所有訪客語言啟動器中使用 --help:tools
選項來顯示 CPU 取樣器、CPU 追蹤器和記憶體追蹤器的參考資訊。目前可用的選項集如下。
CPU 取樣器選項 #
--cpusampler=true|false|<Output>
:啟用/停用 CPU 取樣器,或使用特定輸出啟用 - 由 Output 選項指定(預設:false)。使用此選項選擇輸出預設為將輸出列印到標準輸出,火焰圖除外,該火焰圖會列印到 flamegraph.svg 檔案。--cpusampler.Delay=<ms>
:延遲取樣這麼多毫秒(預設:0)。--cpusampler.FilterFile=<filter>
:來源檔案路徑的萬用字元篩選器。(例如,program.sl)(預設:無篩選器)。--cpusampler.FilterLanguage=<languageId>
:僅分析具有指定 ID 的語言。(例如,js)(預設:分析所有)。--cpusampler.FilterMimeType=<mime-type>
:僅分析具有指定 mime 類型的語言。(例如,application/javascript)(預設:分析所有)--cpusampler.FilterRootName=<filter>
:程式根的萬用字元篩選器。(例如,Math.*)(預設:無篩選器)。--cpusampler.GatherAsyncStackTrace=true|false
:嘗試收集每個取樣的非同步堆疊追蹤元素(預設:true)。停用此選項可能會減少取樣的額外負荷。--cpusampler.GatherHitTimes
:儲存每個取樣的時間戳記。--cpusampler.MinSamples=[0, inf)
:如果元素的取樣少於此值,則從輸出中移除元素(預設:0)--cpusampler.Output=histogram|calltree|json|flamegraph
:將輸出格式指定為下列其中之一:histogram、calltree、json 或 flamegraph(預設:histogram)。--cpusampler.OutputFile=<path>
:將輸出儲存到指定的檔案。輸出預設會列印到輸出串流。--cpusampler.Period=<ms>
:取樣堆疊的間隔(毫秒)(預設:10)--cpusampler.SampleContextInitialization
:啟用在內容初始化期間執行的程式碼取樣--cpusampler.ShowTiers=true|false|0,1,2
:指定是否顯示項目的編譯資訊。您可以指定 'true' 以顯示所有編譯資訊,指定 'false' 以不顯示任何資訊,或指定以逗號分隔的編譯層清單。注意:直譯器視為第 0 層。(預設:false)--cpusampler.StackLimit=[1, inf)
:最大堆疊元素的最大數量(預設:10000)。--cpusampler.SummariseThreads
:將輸出列印為所有「每個執行緒」設定檔的摘要。
CPU 追蹤器選項 #
--cputracer
:啟用 CPU 追蹤器(預設:false)。--cputracer.FilterFile=<filter>
:來源檔案路徑的萬用字元篩選器。(例如,program.sl)(預設:無篩選器)。--cputracer.FilterLanguage=<languageId>
:僅分析具有指定 ID 的語言。(例如,js)(預設:無篩選器)。--cputracer.FilterMimeType=<mime-type>
:僅分析具有 mime 類型的語言。(例如,application/javascript)(預設:無篩選器)。--cputracer.FilterRootName=<filter>
:程式根的萬用字元篩選器。(例如,Math.*)(預設:無篩選器)。--cputracer.Output=histogram|json
:以「長條圖」或「json」形式列印輸出(預設:長條圖)。--cputracer.OutputFile=<path>
:將輸出儲存到指定的檔案。輸出預設會列印到標準輸出串流。--cputracer.TraceCalls
:在追蹤時擷取呼叫(預設:false)。--cputracer.TraceRoots=true|false
:在追蹤時擷取根(預設:true)。--cputracer.TraceStatements
:在追蹤時擷取陳述式(預設:false)。
記憶體追蹤器選項 #
記憶體追蹤器工具目前是一個實驗性工具。請務必將 --experimental-options
旗標作為前綴以啟用 --memtracer
。
--memtracer
:啟用記憶體追蹤器(預設:false)。--memtracer.FilterFile=<filter>
:來源檔案路徑的萬用字元篩選器。(例如,program.sl)(預設:無篩選器)。--memtracer.FilterLanguage=<languageId>
:僅分析具有指定 ID 的語言。(例如 js)(預設:無篩選器)。--memtracer.FilterMimeType=<mime-type>
:僅分析具有 mime 類型的語言。(例如,application/javascript)。(預設:無篩選器)--memtracer.FilterRootName=<filter>
:程式根的萬用字元篩選器。(例如,Math.*)(預設:無篩選器)。--memtracer.Output=typehistogram|histogram|calltree
:以「typehistogram」、「長條圖」或「呼叫樹狀結構」形式列印輸出。(預設:長條圖)--memtracer.StackLimit=[1, inf)
:最大堆疊元素的最大數量。(預設:10000)--memtracer.TraceCalls
:在追蹤時擷取呼叫。(預設:false)--memtracer.TraceRoots=true|false
:在追蹤時擷取根。(預設:true)--memtracer.TraceStatements
:在追蹤時擷取陳述式(預設:false)。