An example of using VTune™ Amplifier XE to profile Java class called by C/C++ application (JNI)

Article <Java support is back in VTune™ Amplifier XE> informs that VTune(TM) Amplifier XE 2013 already supports Java application, and Attaching to Java* processes for hardware event-based sampling is supported since VTune™ Amplifier XE 2013 Update 4.

The problem is that Java class may not be used directly in application. For example, Java application may work with Apache, Tomcat, Php and Mysql, etc. Sometime C/C++ code may call Java methods from class via JNI (Java Native Interface). This article educate to use JNI and how VTune Amplifier collects performance in Java class by JNI mode.

Steps:

1. Create a simple Java class, which has "calc" public method. See attached Demo.java file

2. Use Oracle* JDK 1.7 to compile Demo.java with "-g" option (generate symbol info in class file)

# ../../jdk1.7.0_11/bin/javac -g Demo.java

3. Run Demo class directly

# ../../jdk1.7.0_11/bin/java Demo

Note that “main” public method calls "calc" method in this case.

4. One important thing to be noted here is to specify the function signatures while obtaining the method IDs. To obtain the correct method signature, you can use the following Java comman:

# ../../jdk1.7.0_11/bin/javap -s -p Demo

Compiled from "Demo.java"

public class Demo {

  public Demo();

    Signature: ()V

 

  public static void main(java.lang.String[]);

    Signature: ([Ljava/lang/String;)V

 

  public static void calc();

    Signature: ()V

}

5. Create a test.cpp (see attached), which uses the signature of method "calc"

6. Compile C++ file to generate executable 

g++ -g test.cpp -I/home/peter/jdk1.7.0_11/include -I/home/peter/jdk1.7.0_11/include/linux -L/home/peter/jdk1.7.0_11/jre/lib/amd64/server -ljvm -o test

7. Run C++ binary which calls public method “calc” from Demo class

First, you need to add JRE library into environment variable LD_LIBRARY_PATH 

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/peter/jdk1.7.0_11/jre/lib/amd64/server 

Then run "./test"

8. Now we can profile “calc” java method called by C++ built “test” application

# amplxe-cl -collect hotspots -mrte-mode=auto –duration 20 -- ./test

# amplxe-cl -report callstacks -r r000hs

# amplxe-cl -report callstacksamplxe: Using result path `/home/peter/jni_java/r003hs'

amplxe: Executing actions 50 % Generating a report                            

Function                     Call Stack                            Module                              CPU Time:Self

---------------------------  ------------------------------------  ----------------------------------  -------------

Demo::calc                                                         [Compiled Java code]                19.680

                             call_stub                             [Dynamic code]                      16.960

                             JNIEnv_::CallStaticVoidMethod         test                                0

                             main                                  test                                0

                             __libc_start_main                     libc-2.12.so                        0

9. Also you can attach the process which runs Java method

# ./test &

[1] 16801

# amplxe-cl -collect lightweight-hotspots -knob enable-stack-collection=true -knob enable-call-counts=true -mrte-mode=auto -target-pid 16801

# amplxe-cl -report callstacks

amplxe: Using result path `/home/peter/jni_java/r001lh'

amplxe: Executing actions 50 % Generating a report                            

Function                       Call Stack               Module              CPU Time:Self

-----------------------------  -----------------------  ------------------  -------------

JNIEnv_::CallStaticVoidMethod                           test                20.023

                               main                     test                20.023

                               __libc_start_main        libc-2.12.so        0

                                                                           

pthread_cond_timedwait                                  libpthread-2.12.so  0.002

                               os::PlatformEvent::park  libjvm.so           0.002

                               WatcherThread::run       libjvm.so           0

                               java_start               libjvm.so           0

                               start_thread             libpthread-2.12.so  0

                               clone                    libc-2.12.so        0

AnexoTamanho
Download demo.zip367 bytes
Download test.cpp1.1 KB
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.