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

发布于 2024-07-08 11:05:31 字数 963 浏览 13 评论 0原文

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

  • 执行时间(很可能线程执行时间
  • 内存使用情况
  • CPU 负载(特别是代码段)

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

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

例如:

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 中实现这一目标?

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

我非常高兴能够参考教程或外部示例,并且不期望在这里得到完整的答案。 也就是说,如果能够实现像上面这样简单的事情,那么一个现实的例子就会非常顺利。

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

  • Execution time (most likely thread execution time)
  • Memory usage
  • CPU load (specifically attributable to the code segment)

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.

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.

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?

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

万劫不复 2024-07-15 11:05:31

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

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

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

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

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

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

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).

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.

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

飘落散花 2024-07-15 11:05:31

使用 ThreadMXBean,您可以获得各个线程的 CPU 使用率和消耗的 cpu 时间,而不是可能有用的运行时间。

但是,使用分析器通常更简单,因为此过程通常会生成大量数据,并且您需要一个良好的可视化工具来查看正在发生的情况。

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

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

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)

寄居者 2024-07-15 11:05:31

使用 Java Profiler 是最好的选择,它可以让您深入了解代码。 即响应时间、线程调用跟踪、内存利用率等

我建议您JENSOR,一个开源 Java Profiler,因其易于使用且 CPU 开销较低。 您可以下载它、检测代码并获取有关代码所需的所有信息。

您可以从以下位置下载:http://jensor.sourceforge.net/

Using a Java Profiler is 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

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.

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

溺ぐ爱和你が 2024-07-15 11:05:31

我们可以通过收集执行期间的 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 来完成。

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.

For the CPU you can get its current value :

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文