Measure I / O requirements for a method call

I am interested in performance measurements (CPU and disk I / O requirements) of Java EE applications.

For CPU I already figured out how to measure the CPU demand of each method call. By calling java.lang.management.ThreadMXBean.getCurrentThreadCpuTime () at the beginning and end of each method (for example, using an EJB interceptor), I can get the ("raw") time it takes for the processor to process that method (CPU Demand).

Unfortunately, the I / O request (disk: read and write for each method call) seems to be very difficult to measure. ThreadMXBean does not provide such data. Merely subtracting the above measured CPU request from the total response time of each method is not enough due to the pause and sync times (it would also be nice to distinguish between read and write if possible).

I thought about digging further down to the operating system interfaces to try to call Syscalls or parse other kernel information. I am currently trying to understand how tools like "sar" measure "iowait" times and how I can map such data to my Java streams and related methods. But I'm not sure if I'm heading in the right direction as my deeper OS knowledge is limited.

Long story short : how can I measure the I / O request (disk read and write time) for each of my method calls?

Thanks in advance, bkk

+3


source to share


1 answer


OK, so I recently developed a small utility tool that measures some performance metrics for one of our servers. I went with Java Mission Control (jmc) to record metrics and analyze the recording file later. In my case, the performance test starts the server and attaches the compare tool to it (but you can configure it to attach to an already running instance - this link provides more information on how to do this). I'll give you some essential usage for your lines of code here.

1) Before starting the server, I added to the following JMC config on the command line:

-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder
-XX:StartFlightRecording=delay=5s,duration=120s,name=recording,filename=recording.jfr

      

so when executing the command after a 5 second delay, it started recording with default settings and generated a report file after 120 seconds. 2) I was extracting I / O statistics using the following method:



FlightRecording flightRecording = FlightRecordingLoader.loadFile(new File(...));
IView recording = flightRecording.createView();
for (IEvent event : recording) {
    FLRMethod method = (FLRMethod) event.getValue("((stackTrace).method)");
    /* this shows the bytes read by method at some invocation(if any), 
    so for total bytes read by method you will need to sum manually */
    long bytesRead = Long.valueOf(String.valueOf(event.getValue("bytesRead")));
}

      

You have many opportunities to explore, such as the time it takes to read / write a file, the number of reads, etc. You need to experiment a bit to see some of its features. The latest Java is bundled with the JMC. I've only tried this though with Java 1.7 and 1.8

EDIT: As Klara pointed out, you should consider thresholds that can be configured in your settings file. This way, operations that are less than the specified threshold will not be added to the JFR record.

+1


source







All Articles