16

Consider the two simple Java classes below:

First Example

class Computer {
    Computer() {
        System.out.println("Constructor of Computer class.");
    }
    void On() {
        System.out.println("PC turning on...");
    }
    void working() {
        System.out.println("PC working...");
    }
    void Off() {
        System.out.println("PC shuting down...");
    }
    public static void main(String[] args) {
        Computer my = new Computer();
        Laptop your = new Laptop();
        my.On();
        my.working();
        your.On();
        your.working();
        my.Off();
        your.Off();
   }
}

Second Example

class Laptop {
    Laptop() {
        System.out.println("Constructor of Laptop class.");
    }
    void On() {
        System.out.println("Laptop turning on...");
    }
    void working() {
        System.out.println("Laptop working...");
    }
    void Off() {
        System.out.println("Laptop shuting down...");
    }
}

After the program run, how do I trace (1) which object call which method (2) and how many times?

Just a little precision, I might have 100 classes and 1000s of objects each of them calling 100s of methods. I want to be able to trace (after I run the program), which object called which method and how many times.

Thanks for any suggestion.

4
  • Are you asking about more complex or general examples? From this example, it would be obvious, since you only have one instance of each class and there is no inheritance. Commented Apr 1, 2015 at 3:18
  • 1
    @DanielNugent I am looking for an answer for use in any situation. I might have 100 classes and 1000s of objects calling each 100s of methods. I want to be able to trace (after I run the program), which object called which method and how many times. Thanks - George
    – george24
    Commented Apr 1, 2015 at 3:37
  • @1sand0s Thanks, I am new here. I might have not understand well the code formatting.
    – george24
    Commented Apr 1, 2015 at 3:39
  • @1sand0s I just did the formatting, now it appears ok. Thanks for the tip of leaving 4 spaces.
    – george24
    Commented Apr 1, 2015 at 3:48

2 Answers 2

24

This prints a line for each method call of all objects in all threads:

Runtime.traceMethodCalls() (deprecated / no-op in Java 9)

And

Runtime.traceInstructions (deprecated / no-op in Java 9)

You can use a call tracer like   housemd  or   btrace  or  inTrace

For more involved analysis, you can use a call graph utility like one of these:

(here is an article on the subject)

The deprecated methods above are slated for removal, because there are now JVM-specific alternatives:

  • Java Flight Recorder     Part of JDK 7 as of build 56. Requires commercial license for use in production
  • VisualVM                       Free/popular 3rd party

Both of those tools pretty easy to setup and start collecting information and have nice GUI interfaces. They attach to a running JVM process and allow for thread snapshots and various other kinds of diagnosis (Visual VM has a lot of available plugins but that can take awhile to sort through to configure and understand, if you want to go beyond default behavior, whereas JFR is instrumented with more by default).

Also, don't underestimate the usefulness of JVM distributed command line utilities ($JAVA_HOME/bin), for performing some easily accessible diagnostics.

  • jstack      stack trace
  • jmap       memory map
  • jstat        JVM statistics monitoring
  • jhat         heap analysis tool
  • jdb          debugger
  • jinfo        java process or core file config info
3
  • 1
    Just a note that this method along with traceInstructions() is deprecated starting with Java 9.
    – asgs
    Commented Jan 19, 2017 at 9:28
  • 1
    Also, note that these methods are not only deprecated, but turned into a no-op as well, so users should look for alternatives when migration to JDK 9.
    – asgs
    Commented Jan 19, 2017 at 12:33
  • 1
    Note, it seems traceInstructions() rarely worked, even with old JVMs. I tried with several (6, 7, 8), to no avail. This matches many other reports, for example: stackoverflow.com/a/1025685/7256341
    – valiano
    Commented Apr 29, 2019 at 7:15
0
$ jdb -classpath ... -sourcepath ... my.App
jdb> stop on my.App.main
jdb> run
jdb> step          <... repeat until get to interesting line...>
jdb> threads
jdb> trace go methods 0x1    <... 0x1 is our main thread ID ...>    
jdb> step
                   <...HERE you get full methods calls trace...>
jdb> quit
1
  • 2
    The repeat until get to interesting line part of this answer renders it bogus.
    – markspace
    Commented Sep 9, 2019 at 21:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.