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

余生长醉 提交于 2019-11-27 06:59:30
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).

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

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)

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/

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!