测量代码段的 Java 执行时间、内存使用情况和 CPU 负载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/302026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 12:50:59  来源:igfitidea点击:

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

javaperformancemonitoringjmxmeasurement

提问by Jon Cram

For a particular segment of Java code, I'd like to measure:

对于特定的 Java 代码段,我想测量:

  • Execution time (most likely thread execution time)
  • Memory usage
  • CPU load (specifically attributable to the code segment)
  • 执行时间(最有可能的线程执行时间
  • 内存使用情况
  • CPU 负载(具体归因于代码段)

I'm a relative Java novice and am not familiar with how this might be achieved. I've been referred to JMX, however I'm not sure how that might be used, and JMX looks a bit 'heavy' for what I'm looking to do.

我是一个相对的 Java 新手,不熟悉如何实现这一点。我被称为JMX,但是我不确定如何使用它,而且 JMX 对于我想要做的事情来说看起来有点“沉重”。

Ideally I'd like some measurement class that can be told what I would like to measure, with the option of calling a start()method prior to a code segment and a stop()method after. Relevant metrics would be logged to a file I specify.

理想情况下,我想要一些可以告诉我想要测量什么的测量类,可以选择start()在代码段之前调用方法,然后选择stop()方法。相关指标将记录到我指定的文件中。

For example:

例如:

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();

Is there any standard/common/conventional way of achieving this in Java?

在 Java 中是否有任何标准/通用/传统方法可以实现这一点?

Such measurements are for one-off performance comparisons, and so I'm not looking for any in-production long-term monitoring processes.

此类测量用于一次性性能比较,因此我不寻找任何生产中的长期监控过程。

I'm more than happy to be referred to tutorials or external examples and don't expect a full answer here. That said, if anything as simple as the above can be achieved a realistic example would go down really well.

我很高兴被提及教程或外部示例,并且不期望在这里得到完整的答案。也就是说,如果可以实现像上述那样简单的任何事情,那么现实的例子就会非常好。

采纳答案by basszero

Profiling may be an easier option since you don't require in-production stats. Profiling also doesn't require code modification. VisualVM (which ships w/ the JDK 1.6.06+) is a simple tool. If you want something more in-depth I'd go with Eclipse TPTP, Netbeans profiler, or JProfiler(pay).

分析可能是一个更简单的选择,因为您不需要生产中的统计数据。分析也不需要修改代码。VisualVM(随 JDK 1.6.06+ 一起提供)是一个简单的工具。如果您想要更深入的东西,我会使用 Eclipse TPTP、Netbeans profiler 或 JProfiler(pay)。

If you want to write you own, consider the following:

如果您想自己编写,请考虑以下事项:

Simple measurments like execution time can be done by "clocking" the section you're interested in:

可以通过“计时”您感兴趣的部分来完成诸如执行时间之类的简单测量:

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

You can use a similar technique to monitor memory via Runtime.getRuntime().*memory() methods. Keep in mind that tracking memory usage in a garbage collected environment is trickier than simple subtraction.

您可以使用类似的技术通过 Runtime.getRuntime().*memory() 方法来监视内存。请记住,在垃圾收集环境中跟踪内存使用情况比简单的减法更棘手。

CPU load is hard to measure in Java, I typically stick with execution time and optimize the longer / repetitive sections

在 Java 中很难测量 CPU 负载,我通常坚持执行时间并优化较长/重复的部分

回答by M.N

Using a Java Profileris the best option and it will give you all the insight that you need into the code. viz Response Times, Thread CallTraces, Memory Utilisations, etc

使用 Java Profiler是最好的选择,它将为您提供对代码所需的所有洞察。即响应时间、线程调用跟踪、内存利用率等

I will suggest you JENSOR, an open source Java Profiler, for its ease-of-use and low overheads on CPU. You can download it, instrument the code and will get all the info you need about your code.

我会向您推荐 JENSOR,这是一个开源 Java Profiler,因为它易于使用且 CPU 开销低。您可以下载它,检测代码并获得您需要的关于代码的所有信息。

You can download it from: http://jensor.sourceforge.net/

:你可以从这里下载http://jensor.sourceforge.net/

回答by Peter Lawrey

With the ThreadMXBean you can get CPU usage of individual threads and cpu time consumed rather than elapse time which may be useful.

使用 ThreadMXBean,您可以获得单个线程的 CPU 使用率和消耗的 CPU 时间,而不是可能有用的经过时间。

However, its often simpler to use a profiler as this process often generates a lot of data and you need a good visualisation tool to see what is going on.

然而,使用分析器通常更简单,因为这个过程通常会生成大量数据,您需要一个好的可视化工具来查看发生了什么。

I use Yourkit as I find it easier to solve problems that other profilers I have used. I also use the builtin hprof as this can give you a different view on the profile of your application (but not as useful)

我使用 Yourkit 是因为我发现解决我使用过的其他分析器的问题更容易。我还使用内置的 hprof,因为这可以让您对应用程序的配置文件有不同的看法(但没那么有用)

回答by davidxxx

We can measure the cpu and memory used during a specific invoked method by collecting the cpu and memory metrics during its execution.
Of course if other concurrent threads for other methods consumes memory and cpu during its execution, you are stuck. So it is a valid approach while you are able to execute a method in a isolated way.

我们可以通过收集执行期间的 cpu 和内存指标来测量特定调用方法期间使用的 cpu 和内存。
当然,如果其他方法的其他并发线程在执行过程中消耗了内存和cpu,你就卡住了。因此,当您能够以隔离的方式执行方法时,这是一种有效的方法。

For the CPU you can get its current value :

对于 CPU,您可以获取其当前值:

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

For the memory you can do that :

对于内存,您可以这样做:

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

About the memory measure, waiting for a major collect before executing the method improves its reliability.

关于内存度量,在执行该方法之前等待主要收集提高了其可靠性。

For example something like that may help :

例如,这样的事情可能会有所帮助:

import com.google.common.testing.GcFinalization;

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

GcFinalizationcomes from the Guava test library.

GcFinalization来自Guava 测试库

All that has few overheads. So the idea is collecting metrics (for example each second) for each invoked method you want to monitor and when the method returned, compute the max/average or any useful information for them.

所有这些都没有什么开销。因此,我们的想法是为您要监视的每个调用的方法收集指标(例如每秒),并在方法返回时计算最大值/平均值或任何有用的信息。

I would favor AOP to do that.
Spring AOP is a simple and good way to create aspects and set pointcuts for them but you can also do it with AspectJ if you need some particular things in terms of AOP features.

我赞成 AOP 这样做。
Spring AOP 是一种创建方面并为它们设置切入点的简单而好方法,但如果您需要 AOP 特性方面的某些特定内容,您也可以使用 AspectJ 来完成。