Giter VIP home page Giter VIP logo

adoptopenjdk / jitwatch Goto Github PK

View Code? Open in Web Editor NEW
3.0K 156.0 430.0 5.31 MB

Log analyser / visualiser for Java HotSpot JIT compiler. Inspect inlining decisions, hot methods, bytecode, and assembly. View results in the JavaFX user interface.

License: Other

Shell 0.33% Java 99.41% Groovy 0.01% Scala 0.03% CSS 0.02% Kotlin 0.01% Batchfile 0.18% JavaScript 0.01%
jitwatch java javafx hotspot-jit-compiler hotspot log-analyser jit-compiler escape-analysis

jitwatch's Introduction

JITWatch

Log analyser and visualiser for the HotSpot JIT compiler.

  • Video introduction to JITWatch video
  • Slides from my LJC lightning talk on JITWatch slides

For instructions and screenshots see the wiki

The JITWatch user interface is built using JavaFX which is downloaded as a maven dependency for JDK11+.

For pre-JDK11 you will need to use a Java runtime that includes JavaFX.

maven

mvn clean package && java -jar ui/target/jitwatch-ui-shaded.jar

Build an example HotSpot log

# Build the code and then run
cd scripts && ./makeDemoLogFile.sh

jitwatch's People

Contributors

aalmiray avatar akbertram avatar alblue avatar cajogos avatar chrisvest avatar chriswhocodes avatar civanyp avatar cyberdak avatar ferstl avatar fthevenet avatar garyttierney avatar geertjanw avatar gvdutra avatar hutupro avatar hyperpape avatar jcwasmx86 avatar karianna avatar kittylyst avatar ldebello avatar marshallpierce avatar neomatrix369 avatar nhojpatrick avatar pcdv avatar philipa avatar picpromusic avatar renelink avatar schlosna avatar testboost avatar trask avatar yole avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jitwatch's Issues

Bytecode viewer not matching methods with generics in signature

Didn't realise that com.sun.tools.javap.JavapTask bytecode disassembly includes generics in method signatures.

My BytecodeLoader class parses the JavapTask output and builds a Map of method signature to bytecode. The Map is searched using the type-erased signature so is failing to load generics method sigs.

Example: java.util.Arrays

public static <T extends java/lang/Object, U extends java/lang/Object> T[] copyOf(U[], int, java.lang.Class<? extends T[]>);
    Code:
       0: aload_2       
       1: ldc_w         #21                 // class "[Ljava/lang/Object;"
       4: if_acmpne     17
...

Cleaner launchUI.sh suggestion.

Here is a small change I made to launchUI.sh to make it automatically pick up the JDK_HOME on MacOS X.

#!/bin/sh

unamestr=`uname`
if [[ "$unamestr" == 'Darwin' ]]; then
   export JDK_HOME=`/usr/libexec/java_home`
fi

export CP=$JDK_HOME/lib/tools.jar:$JDK_HOME/jre/lib/jfxrt.jar:target/jitwatch-1.0.0-SNAPSHOT.jar
$JDK_HOME/bin/java -cp $CP com.chrisnewland.jitwatch.launch.LaunchUI

Note there are back ticks around the uname and the java_home commands. As other users (ie. Linux) make suggestions for detecting the Java home on their platform additional conditionals can be added.

Investigate why classloading log statements are not atomic with native code dumps

Decoding compiled method 0x009e06c8:
Code:
[Entry Point]
[Constants]
  # {method} 'ind

[Loaded sun.nio.cs.ThreadLocalCoders from C:\Program Files\Java\jre7\lib\rt.jar]

exOf' '(II)I' in 'java/lang/String'
  # this:     ecx       = 'java/lang/String'
  # parm0:    edx       = int
  # parm1:    [sp+0x20]   = int  (sp of caller)
  0x009e07e0: nop
  0x009e07e1: nop
  0x009e07e2: nop

Warning if mounted classes compiled with different compiler to that which produced the hotspot.log

If classes are compiled with javac A and the hotspot.log file is produced by running those classes then you must run JITWatch and mount the same classes.

If you run JITWatch using mounted classes that were compiled with javac B then javap may not disassemble the same bytecode offsets and JITWatch won't be able to annotate the bytecode correctly (offsets won't match).

Need to detect this (class version in header?) and show a warning.

Sources and class files for inner classes are not picked up.

One such example that shows up in my error logs is java.util.HashMap$Entry, and java.util.concurrent.ThreadLocalRandom$1 is another. But it's also a problem for my own code, even if I point out the containing files directly by adding them to the configuration.

JavaFX / graphics card error when running ./launchUI.sh on Linux

When I run

mvn clean compile test exec:java

I get the below error:

.
.
.
[log messages]
.
.
.
X Error of failed request:  BadRequest (invalid request code or no such operation)
  Major opcode of failed request:  136 (GLX)
  Minor opcode of failed request:  19 (X_GLXQueryServerString)
  Serial number of failed request:  12
  Current serial number in output stream:  12

Is this a known issue ? I also get it after running the below as well:

./launchUI.sh

but the below works fine:

./launchHeadless.sh hotspot.log

Is it specific to my OS?

Unload classes once member information obtained to avoid PermGen errors

Running JITWatch with a hotspot log file that references a lot of classes (e.g. from Eclipse) can cause a PermGen memory error due to classloading.

JITWatch only loads the classes to scrape the methods and constructors into IMetaMember objected so the classes should be unloaded afterwards.

Parsing Errors

I run into quite a few parsing issues, e.g.

Could not parse line 579 : decode ([BII[C)I[Loaded sun.awt.image.SurfaceManager$ProxiedGraphicsConfig from .opt.java.jre.lib.rt.jar]
Could not parse line 19222 : java.util.Properties$Li[Loaded sun.awt.X11.PropMwmHints from .opt.java.jre.lib.rt.jar] readLine ()I
Could not parse line 35488 : [Loaded java.awt.im.spi.InputMethod from .opt.java.jre.lib.rt.jar] loadConvert ([CII[C)Ljava.lang.String;

The word-wrapping doesn't seem to be an issue (at least fixing this didn't help). The problem appears to be the obviously race-conditionally inlined "[Loaded ... from ...]" (most obvious in the 2nd case):

  # {method} 'decode' '([BII[C)I'[Loaded sun.awt.image.SurfaceManager$ProxiedGraphicsConfig from /opt/java/jre/lib/rt.jar]
 in 'sun/nio/cs/UTF_8$Decoder'
  # {method} 'readLine' '()I' in 'java/util/Properties$Li[Loaded sun.awt.X11.PropMwmHints from /opt/java/jre/lib/rt.jar]
neReader'
  # {method} 'loadConvert' '([CII[C)Ljava/lang/String;' in '[Loaded java.awt.im.spi.InputMethod from /opt/java/jre/lib/rt.jar]
java/util/Properties'

After fixing these lines no parsing errors were reported. But that's it. No GUI update, no CPU activity, no stdout output (mvn exec:java), nothing.

Dumped with

java -XX:+UnlockDiagnosticVMOptions -XX:+TraceClassLoading -XX:+LogCompilation -XX:+PrintAssembly 

and

java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

And the 4yo linux hsdis from https://kenai.com/projects/base-hsdis/downloads

78b183b38cdf4f2396478a9086bac96cdfd7a4db  /opt/java/jre/lib/amd64/server/hsdis-amd64.so

Remove package filter

Doesn't seem a useful feature. Checking most likely slows down the code. Building entire tree probably the usual use case.

java.lang.NumberFormatException when clicking on "Start"

After loading a log file and clicking "Start" I'm getting the following stack trace:

java.lang.NumberFormatException: For input string: "0,151"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
at java.lang.Double.parseDouble(Double.java:540)
at com.chrisnewland.jitwatch.util.ParseUtil.parseStamp(ParseUtil.java:47)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethod(HotSpotLogParser.java:374)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethodLine(HotSpotLogParser.java:331)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleTag(HotSpotLogParser.java:235)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleLine(HotSpotLogParser.java:189)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.watch(HotSpotLogParser.java:104)
at com.chrisnewland.jitwatch.ui.JITWatchUI$1.run(JITWatchUI.java:159)
at java.lang.Thread.run(Thread.java:724)
java.lang.NumberFormatException: For input string: "0,218"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
at java.lang.Double.parseDouble(Double.java:540)
at com.chrisnewland.jitwatch.util.ParseUtil.parseStamp(ParseUtil.java:47)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethod(HotSpotLogParser.java:374)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethodLine(HotSpotLogParser.java:331)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleTag(HotSpotLogParser.java:239)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleLine(HotSpotLogParser.java:189)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.watch(HotSpotLogParser.java:104)
at com.chrisnewland.jitwatch.ui.JITWatchUI$1.run(JITWatchUI.java:159)
at java.lang.Thread.run(Thread.java:724)
java.lang.NumberFormatException: For input string: "0,251"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
at java.lang.Double.parseDouble(Double.java:540)
at com.chrisnewland.jitwatch.util.ParseUtil.parseStamp(ParseUtil.java:47)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethod(HotSpotLogParser.java:374)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethodLine(HotSpotLogParser.java:331)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleTag(HotSpotLogParser.java:235)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleLine(HotSpotLogParser.java:189)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.watch(HotSpotLogParser.java:104)
at com.chrisnewland.jitwatch.ui.JITWatchUI$1.run(JITWatchUI.java:159)
at java.lang.Thread.run(Thread.java:724)
java.lang.NumberFormatException: For input string: "0,260"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
at java.lang.Double.parseDouble(Double.java:540)
at com.chrisnewland.jitwatch.util.ParseUtil.parseStamp(ParseUtil.java:47)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethod(HotSpotLogParser.java:374)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethodLine(HotSpotLogParser.java:331)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleTag(HotSpotLogParser.java:239)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleLine(HotSpotLogParser.java:189)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.watch(HotSpotLogParser.java:104)
at com.chrisnewland.jitwatch.ui.JITWatchUI$1.run(JITWatchUI.java:159)
at java.lang.Thread.run(Thread.java:724)
java.lang.NumberFormatException: For input string: "0,251"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
at java.lang.Double.parseDouble(Double.java:540)
at com.chrisnewland.jitwatch.util.ParseUtil.parseStamp(ParseUtil.java:47)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethod(HotSpotLogParser.java:374)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethodLine(HotSpotLogParser.java:331)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleTag(HotSpotLogParser.java:243)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleLine(HotSpotLogParser.java:189)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.watch(HotSpotLogParser.java:104)
at com.chrisnewland.jitwatch.ui.JITWatchUI$1.run(JITWatchUI.java:159)
at java.lang.Thread.run(Thread.java:724)
java.lang.NumberFormatException: For input string: "0,151"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
at java.lang.Double.parseDouble(Double.java:540)
at com.chrisnewland.jitwatch.util.ParseUtil.parseStamp(ParseUtil.java:47)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethod(HotSpotLogParser.java:374)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethodLine(HotSpotLogParser.java:331)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleTag(HotSpotLogParser.java:243)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleLine(HotSpotLogParser.java:189)
at com.chrisnewland.jitwatch.core.HotSpotLogParser.watch(HotSpotLogParser.java:104)
at com.chrisnewland.jitwatch.ui.JITWatchUI$1.run(JITWatchUI.java:159)
at java.lang.Thread.run(Thread.java:724)
...

The log file has been generated when running a program as follows:

java -XX:+UnlockDiagnosticVMOptions -XX:+TraceClassLoading -XX:+LogCompilation -XX:+PrintAssembly Test

Additional information:
java -version
java version "1.7.0_25"
OpenJDK Runtime Environment (IcedTea 2.3.12) (7u25-2.3.12-4ubuntu3)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)

NumberFormatException

Using the latest jar from cloudbees for OpenJDK 8:

[Thread-3] ERROR com.chrisnewland.jitwatch.core.HotSpotLogParser - Exception handling: '<nmethod compile_id='32' compiler='C1' level='1' entry='0x00007ffdb5117320' size='704' address='0x00007ffdb51171d0' relocation_offset='288' insts_offset='336' stub_offset='464' scopes_data_offset='616' scopes_pcs_offset='632' dependencies_offset='696' method='java/nio/Buffer limit ()I' bytes='5' count='155' iicount='155' stamp='1,165'/>' java.lang.NumberFormatException

Using older jar:

Exception handling: '<nmethod compile_id='32' compiler='C1' level='1' entry='0x00007ffdb5117320' size='704' address='0x00007ffdb51171d0' relocation_offset='288' insts_offset='336' stub_offset='464' scopes_data_offset='616' scopes_pcs_offset='632' dependencies_offset='696' method='java/nio/Buffer limit ()I' bytes='5' count='155' iicount='155' stamp='1,165'/>'
java.lang.NumberFormatException
    at java.math.BigDecimal.<init>(BigDecimal.java:494)
    at java.math.BigDecimal.<init>(BigDecimal.java:383)
    at java.math.BigDecimal.<init>(BigDecimal.java:806)
    at com.chrisnewland.jitwatch.model.JITDataModel.updateStats(JITDataModel.java:176)
    at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethod(HotSpotLogParser.java:392)
    at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleMethodLine(HotSpotLogParser.java:334)
    at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleTag(HotSpotLogParser.java:242)
    at com.chrisnewland.jitwatch.core.HotSpotLogParser.handleLine(HotSpotLogParser.java:192)
    at com.chrisnewland.jitwatch.core.HotSpotLogParser.watch(HotSpotLogParser.java:106)
    at com.chrisnewland.jitwatch.ui.JITWatchUI$1.run(JITWatchUI.java:171)
    at java.lang.Thread.run(Thread.java:745)

Correct handling of Java 8 tiered compilation logs

Java 8 default JIT mode is tiered and I built JITWatch on Java 7 64 bit where the default mode is server (C2 compiler). There are a few bad assumptions about the XML structure that need regression testing and then fixing before JITWatch will work correctly with Java 8 tiered compilation logs.

JITWatch can't eat it's own dogfood (Classloader issue)

If you try to analyse JITWatch by mounting jxfrt.jar or the JITWatch classes in JITWatch it failed with java.lang.IllegalAccessError.

Need to fix classloader usage so that the mounted classes use the right classloader.

Sandbox - JITWatch will not reload modified classes

Oh ffs Chris! Should have realised this from the start.

Currently if you run the sandbox, add a method to a sandbox class, and then re-run it the class file on disk will contain the new method and so will the sandbox's hotspot log but the main JITWatch program will not load the modified class (since it uses the system classloader which has already loaded the class).

JITWatch needs to use a disposable classloader when loading classes found in the hotspot log so that it can parse multiple logs per user session (typical sandbox usage).

Fix parser for JDK8 hotspot.log format (URGENT)

Received this error report from a user:
Could not parse line 64 : java.lang.String {0x00007f5734d11f80} hashCode ()I
Could not parse line 254 : java.lang.String {0x00007f5734d115a0} equals
(Ljava.lang.Object;)Z
Could not parse line 585 : java.lang.Object {0x00007f5734d0d488} ()V
Could not parse line 679 : java.lang.String {0x00007f5734d10d38} charAt (I)C
Could not parse line 860 : java.lang.System {0x00007f5734d263e8} arraycopy
(Ljava.lang.Object;ILjava.lang.Object;II)V
Could not parse line 980 : java.lang.Math {0x00007f5734dcb570} min (II)I
Could not parse line 1080 : java.lang.String {0x00007f5734d10be8} length ()I
Could not parse line 1183 : java.lang.String {0x00007f5734d12100} indexOf (II)I
Could not parse line 1453 : java.lang.AbstractStringBuilder {0x00007f5734d7d668}
ensureCapacityInternal (I)V
Could not parse line 1611 : java.lang.Object {0x00007f5734d0d488} ()V
Could not parse line 1704 : java.util.Arrays {0x00007f5734e0c260} copyOfRange ([CII)[C
Could not parse line 2395 : java.io.DataInputStream {0x00007f5734f35a58} readUTF
(Ljava.io.DataInput;)Ljava.lang.String;
...

Looks like the hotspot.log format has changed. Need to investigate and fix, probably by abstracting out the parser and having versions for different hotspot releases.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.