Profiling Java Application with Systemtap

https://laurent-leturgez.com/2017/12/22/profiling-java-application-with-systemtap/

https://myaut.github.io/dtrace-stap-book/app/java.html

I’m not a JVM internals geek but I was sure there was a way to do the job without restarting the JVM, and I found some cool stuff with Systemtap.

To do this, you have to install two packages on your linux distribution: systemtap and systemtap-runtime-java (and configure correctly your user environment):

[[email protected] ~]# yum install systemtap systemtap-runtime-java

Please note that I used a CentOS 7.4 distribution.

Then, and for the demo, I wrote a very small piece of Java that do these steps:

  1. Prints the JVM PID
  2. Wait for a key to be pressed. During this time, you will have to execute the systemtap script I will described later.
  3. Execute a loop ten times, each loop with print a message and wait one second, and this last step is executed in a method name “loop_and_wait”.

Here’s the sample code:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

package com.premiseo;

import java.lang.*;

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.io.IOException;

class Example {

   public static void loop_and_wait(int n) throws InterruptedException{

           System.out.println("Waiting "+n+"ms... Tick");

           Thread.sleep(n);

        }

   public static void main(String[] args) {

      System.out.println("PID = "+java.lang.management.ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);

      System.out.println("Press any key when ready ...");

      try {

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

        String next = in.readLine();

      }

      catch (IOException ioe) {

        ioe.printStackTrace();

      }

      try {

        for (int i=0;i<10;i++) {

           loop_and_wait(1000);

        }

      }

      catch (InterruptedException ie) {

        ie.printStackTrace();

      }

   }

}

Then, compile and execute … very basic I said

[[email protected] java]$ javac -cp $CLASSPATH:. com/premiseo/Example.java
[[email protected] java]$ java -cp $CLASSPATH:. com.premiseo.Example
PID = 9928
Press any key when ready ...

Waiting 1000ms... Tick
Waiting 1000ms... Tick
Waiting 1000ms... Tick
Waiting 1000ms... Tick
Waiting 1000ms... Tick
Waiting 1000ms... Tick
Waiting 1000ms... Tick
Waiting 1000ms... Tick
Waiting 1000ms... Tick
Waiting 1000ms... Tick

Now, to answer to Tanel, I used a short systemtap script that will profile the program and specially the loop_and_wait method. I will count the number of times the loop_and_wait method has been called, and I will account the time spent in this method execution.

To do that, I had to write two probes related to:

  • the full name of the class, including the package name: com.premiseo.Example
  • the class name where the method is defined: Example
  • the method name I want to profile: loop_and_wait

The first one will be executed when the program will start to execute the targeted method (java(“com.premiseo.Example”).class(“Example”).method(“loop_and_wait”)), the second one will be executed when the method will return (java(“com.premiseo.Example”).class(“Example”).method(“loop_and_wait”).return)

The related systemtap script is given below:

#!/usr/bin/env stap

global counter,timespent,t

probe begin {
  printf("Press Ctrl+C to stop profiling\n")
  counter=0
  timespent=0
}

probe java("com.premiseo.Example").class("Example").method("loop_and_wait")
{
  counter++
  t=gettimeofday_ms()
}

probe java("com.premiseo.Example").class("Example").method("loop_and_wait").return
{
  timespent+=gettimeofday_ms()-t
}

probe end {
   printf("Number of calls for loop_and_wait method: %ld \n",    counter)
   printf("Time Spent in method loop_and_wait: %ld msecs \n", timespent)
}

Execution of this systemtap script gave the following result (click the image for full size):

Is it dynamic? Yes, no need to restart the running JVM process you want to target. If you want to target a specific JVM process id, you can use the stap’s “-x” option, add the modify your probe definition like this:

probe java("com.premiseo.Example").class("Example").method("loop_and_wait")
{
  if (pid() == target())
    counter++
    t=gettimeofday_ms()
}

There’s a limitation, you cannot use wilcards in the java probe definition (java(“com.premiseo.Example”).class(“Example”).method(“loop*”) … for example). That would have been useful to profile a set of methods in the same class … but not possible currently.

If you want to read more about this kind of stuff, please read the following websites:

And … that’s all for today !!

时间: 2024-11-09 17:46:36

Profiling Java Application with Systemtap的相关文章

Java application 性能分析分享

性能分析的主要方式 监视:监视是一种用来查看应用程序运行时行为的一般方法.通常会有多个视图(View)分别实时地显示 CPU 使用情况.内存使用情况.线程状态以及其他一些有用的信息,以便用户能很快地发现问题的关键所在. 转储:性能分析工具从内存中获得当前状态数据并存储到文件用于静态的性能分析.Java 程序是通过在启动 Java 程序时添加适当的条件参数来触发转储操作的.它包括以下三种: 系统转储:JVM 生成的本地系统的转储,又称作核心转储.一般的,系统转储数据量大,需要平台相关的工具去分析,

java 远程调试(java application与web application)

如摘要中所述,在联调时经常性的需要将程序部署到测试机器上,此时要调试显得很不方便.以前的做法都是在程序中打印信息来进行追踪,但是这种方法很有局限性,因为往往无法一次就定位到有问题的地方,需要不断的修改程序打印的语句,不断的重启应用,这需要花费大量的时间和精力.因此,采用远程调试会是一种好的解决方式.下面将会对java application和web application两种入手进行说明. 一.Java Application的远程调试 1.准备要调试的server端环境 首先准备一段小的代码,

win10+eclipse+hadoop2.7.2+maven直接通过Run as Java Application运行wordcount

一.准备工作 (1)Hadoop2.7.2 在linux部署完毕,成功启动dfs和yarn,通过jps查看,进程都存在 (2)安装maven 二.最终效果 在windows系统中,直接通过Run as Java Application运行wordcount,而不需要先打包成jar包,然后在linux终端运行 三,操作步骤 1.启动dfs和yarn 终端:${HADOOP_HOME}/sbin/start-dfs.sh ${HADOOP_HOME}/sbin/start-yarn.sh 通过在na

remote java application

remote java application remote java application

maven: 打包可运行的jar包(java application)及依赖项处理

IDE环境中,可以直接用exec-maven-plugin插件来运行java application,类似下面这样: 1 <plugin> 2 <groupId>org.codehaus.mojo</groupId> 3 <artifactId>exec-maven-plugin</artifactId> 4 <version>1.2.1</version> 5 <executions> 6 <execu

解决Run As -&gt; Java Application不能运行问题

转自:https://breakshell.iteye.com/blog/467130 点 Run As -> Java Application 不能运行,报的错误如下: Java代码   Plug-in org.eclipse.ajdt.ui was unable to load class org.eclipse.ajdt.internal.ui.ajde.CachedRuntimeClasspathEntryResolver. org.eclipse.core.runtime.intern

Using properties file in java application

Properties files are a cool place to store your configuration details like database connection properties, error messages and other configurations for your program. You can use properties file in your application using following utility class. This c

springload热部署Java Application项目

对于运维人员来说,热部署是常常要思考的一个问题.热部署简单来说,就是局部或者某个文件修改后,不用重新启动程序,立即生效. 好处在于在程序初始化的时候可能会加载大量的初始化数据,重启程序成本太高:程序如果是项目中的单个模块,重启会影响别的应用. 对于web程序来说,大多是部署在Servlet容器里面,如jBoss,weblogic,tomcat等,这些容器往往提供了配套的热部署方案. 但对于application程序,往往没有厂家单独来做这件事情. 经过本人的搜索,发现springload是一个较

The difference between java application library and java web lib

I remebered that i had writed a java web programming.At that time, i added jar packages by "build path" so that i could import a user library path at firstly. When the path of jar library had been imported into eclipse,to complise program was ri