簡體   English   中英

測量代碼段的Java執行時間,內存使用率和CPU負載

[英]Measuring Java execution time, memory usage and CPU load for a code segment

對於Java代碼的特定部分,我想測量:

  • 執行時間(最有可能的線程執行時間
  • 內存使用情況
  • CPU負載(具體可歸因於代碼段)

我是Java的相對新手,不熟悉如何實現。 我曾經被提到過JMX ,但是我不確定如何使用它,而JMX對於我想做的事情看起來有點“沉重”。

理想情況下,我想要一些可以告訴我要測量什么的測量類,可以選擇在代碼段之前調用start()方法,然后在代碼段之后調用stop()方法。 相關指標將記錄到我指定的文件中。

例如:

import com.example.metricLogger;

metricLogger logger = new metricLogger();

logger.setLogPath(pathToLogFile);
logger.monitor(executionTime);
logger.monitor(memoryUsage);
logger.monitor(cpuLoad);

logger.start();

/* Code to be measured */

logger.stop();

在Java中是否有任何標准/通用/常規方式來實現這一目標?

此類測量是用於一次性性能比較,因此,我不需要任何生產中的長期監控過程。

我很樂意參考教程或外部示例,並且不期望在這里得到完整的答案。 就是說,如果可以實現上述任何簡單的事情,那么一個實際的例子肯定會失敗。

由於您不需要生產統計信息,因此分析可能是一個更簡單的選擇。 分析也不需要修改代碼。 VisualVM(附帶JDK 1.6.06+)是一個簡單的工具。 如果您想更深入地了解,我會選擇Eclipse TPTP,Netbeans profiler或JProfiler(pay)。

如果要自己寫,請考慮以下幾點:

可以通過“計時”您感興趣的部分來完成諸如執行時間之類的簡單測量:

long start = System.nanoTime(); // requires java 1.5
// Segment to monitor
double elapsedTimeInSec = (System.nanoTime() - start) * 1.0e-9;

您可以通過Runtime.getRuntime()。* memory()方法使用類似的技術來監視內存。 請記住,在垃圾收集環境中跟蹤內存使用情況比簡單的減法要難得多。

在Java中,CPU負載很難衡量,我通常會堅持執行時間並優化較長/重復的部分

使用ThreadMXBean,您可以獲得各個線程的CPU使用率和所消耗的cpu時間,而不是經過時間,這可能很有用。

但是,使用探查器通常更簡單,因為此過程通常會生成大量數據,並且您需要一個良好的可視化工具來查看發生了什么。

我使用Yourkit是因為我發現它更容易解決我使用過的其他探查器的問題。 我還使用了內置的hprof,因為它可以為您提供有關應用程序配置文件的不同視圖(但不太有用)

使用Java Profiler是最好的選擇,它將為您提供所有需要的代碼見解。 即響應時間,線程調用跟蹤,內存利用率等

我將建議您JENSOR ,它是開放源代碼Java Profiler,因為它易於使用且CPU開銷低。 您可以下載它,分析代碼,然后獲取所有需要的代碼信息。

您可以從以下網址下載: http//jensor.sourceforge.net/

通過收集執行期間的cpu和內存指標,我們可以測量特定調用方法使用的cpu和內存。
當然,如果其他方法的其他並發線程在執行過程中消耗內存和cpu,則會陷入困境。 因此,當您能夠以隔離方式執行方法時,這是一種有效的方法。

對於CPU,您可以獲取其當前值:

OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
            OperatingSystemMXBean.class); 
double processCpuLoad = osBean.getProcessCpuLoad();

對於內存,您可以這樣做:

MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
int currentHeapUsedInMo = (int) (memoryMXBean.getHeapMemoryUsage().getUsed() / 1_000_000);

關於存儲措施,在執行該方法之前等待主要收集可提高其可靠性。

例如類似的事情可能會有所幫助:

import com.google.common.testing.GcFinalization;

GcFinalization.awaitFullGc();
foo.execute(); // method to execute

GcFinalization來自Guava測試庫

所有這些開銷很少。 因此,該想法是為要監視的每個調用方法收集指標(例如每秒),並在方法返回時為它們計算最大值/平均值或任何有用的信息。

我希望AOP能夠做到這一點。
Spring AOP是一種創建方面和為其設置切入點的簡單且不錯的方法,但是如果您需要一些有關AOP功能的特定內容,也可以使用AspectJ進行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM