简体   繁体   English

测量代码段的Java执行时间,内存使用率和CPU负载

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

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. 我是Java的相对新手,不熟悉如何实现。 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. 我曾经被提到过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. 理想情况下,我想要一些可以告诉我要测量什么的测量类,可以选择在代码段之前调用start()方法,然后在代码段之后调用stop()方法。 Relevant metrics would be logged to a file I specify. 相关指标将记录到我指定的文件中。

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. 就是说,如果可以实现上述任何简单的事情,那么一个实际的例子肯定会失败。

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. VisualVM(附带JDK 1.6.06+)是一个简单的工具。 If you want something more in-depth I'd go with Eclipse TPTP, Netbeans profiler, or JProfiler(pay). 如果您想更深入地了解,我会选择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. 您可以通过Runtime.getRuntime()。* memory()方法使用类似的技术来监视内存。 Keep in mind that tracking memory usage in a garbage collected environment is trickier than simple subtraction. 请记住,在垃圾收集环境中跟踪内存使用情况比简单的减法要难得多。

CPU load is hard to measure in Java, I typically stick with execution time and optimize the longer / repetitive sections 在Java中,CPU负载很难衡量,我通常会坚持执行时间并优化较长/重复的部分

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. 我使用Yourkit是因为我发现它更容易解决我使用过的其他探查器的问题。 I also use the builtin hprof as this can give you a different view on the profile of your application (but not as useful) 我还使用了内置的hprof,因为它可以为您提供有关应用程序配置文件的不同视图(但不太有用)

Using a Java Profiler is the best option and it will give you all the insight that you need into the code. 使用Java Profiler是最好的选择,它将为您提供所有需要的代码见解。 viz Response Times, Thread CallTraces, Memory Utilisations, etc 即响应时间,线程调用跟踪,内存利用率等

I will suggest you JENSOR , an open source Java Profiler, for its ease-of-use and low overheads on CPU. 我将建议您JENSOR ,它是开放源代码Java Profiler,因为它易于使用且CPU开销低。 You can download it, instrument the code and will get all the info you need about your code. 您可以下载它,分析代码,然后获取所有需要的代码信息。

You can download it from: http://jensor.sourceforge.net / 您可以从以下网址下载: http//jensor.sourceforge.net/

We can measure the cpu and memory used during a specific invoked method by collecting the cpu and memory metrics during its execution. 通过收集执行期间的cpu和内存指标,我们可以测量特定调用方法使用的cpu和内存。
Of course if other concurrent threads for other methods consumes memory and cpu during its execution, you are stuck. 当然,如果其他方法的其他并发线程在执行过程中消耗内存和cpu,则会陷入困境。 So it is a valid approach while you are able to execute a method in a isolated way. 因此,当您能够以隔离方式执行方法时,这是一种有效的方法。

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

GcFinalization comes 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. 我希望AOP能够做到这一点。
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. Spring AOP是一种创建方面和为其设置切入点的简单且不错的方法,但是如果您需要一些有关AOP功能的特定内容,也可以使用AspectJ进行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM