Giter Club home page Giter Club logo

jvm-tools's Introduction

Swiss Java Knife (SJK)

SJK is a command line tool for JVM diagnostic, troubleshooting and profiling.

SJK exploits standard diagnostic interfaces of JVM (such as JMX, JVM attach and perf counters) and adds some more logic on top useful for common troubleshooting cases. SJK can also be used as a library for building application specific diagnostic tools or to enhance your code with self monitoring features.

What you can do with SJK?

See full command reference.

Download

Latest prebuild binaries Last Version

  • wget https://training.ragozin.info/sjk.jar -> sjk.jar

Starting sjk

java -jar sjk.jar <cmd> <arguments>
java -jar sjk.jar --commands
java -jar sjk.jar --help <cmd>

Below a few command from SJK (full command reference).

Pools thread CPU usage of the target JVM and periodically reports to the console.

  • can attach via PID or open JMX port
  • displays thread memory allocation rate and cumulative process allocation rate
  • displays safe point time consumption (only if attache via PID)

More details

Similar to jmap -histo.

  • plus can show a histogram of dead objects (histograms of all and live requested, then difference is calculated)
  • plus can show N top buckets in histogram

More details

These commands provide basic sample profiler capabilities. stcap produces hyper-dense stack trace dump (about 1000 compression rate compared to text format) and ssa provides few reports over dump files. stcpy can copy data in archives produced by stcap (e.g. merging dumps or filtering selected threads).

So far following reports are available:

  • sophisticated filtering (time, stack trace, thread name)
  • stack frame histogram with advanced filtering options
  • flame graph visualization (SVG or interactive HTML)
  • per thread summary (CPU usage, memory allocation, etc)
  • converting back to text format

Dump file can be also processed programatically.

More details

This command allows you to do basic operations with MBean from command line.

It can:

  • read MBean attributes
  • update MBean writeable attributes
  • invoke MBean operations (arguments are supported)
  • display composite and tabular data in a human readable format
  • use wild cards to shorten MBean names (e.g. *:*,name=CodeCacheManager instead of java.lang:type=MemoryManager,name=CodeCacheManager)
  • connect to local JVM processes by PID (e.i. any Java process, you do not need to enable JMX server)
  • connect to JMX using host:port (password authentication is supported)

More details

Similar to jps from JDK.

  • plus can display specific system properties of process in output
  • plus can display values of specific -XX for HotSpot JVM processes
  • plus can filter process java processes by their system properties

More details

Report information about GC in real time. Data is retrieved via JMX.

More details

mxdump

Dumps all MBeans of target java process to JSON.

jvm-tools's People

Contributors

alexott avatar aragozin avatar benbenw avatar bjansen avatar deverton avatar dspavlov avatar elvyssoares avatar gquintana avatar ivannik avatar kyxap1 avatar loverdos avatar orthographic-pedant avatar pe4enko avatar petersear avatar php-coder avatar romaindequidt avatar sirvaulterscoff avatar snazy avatar stefan-reich avatar tandronicus avatar tomekp 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

jvm-tools's Issues

ttop not working

What am I doing wrong? This is JDK 10 on Linux. Does the other process need special options?

stefan@stefan-quadcore ~/dev/jvm-tools/sjk/target $ java -jar sjk-0.11-SNAPSHOT.jar ttop -p 13491
Restarting java with unlocked package access
Failed to access MBean server: 13491

Greetings

sjk 0.10 doesn't handle jfr.

Locally builded sjk-plus 0.10 or downloaded from maven central doesn't handle java flight recording.
Version 0.9.3 works.

java -jar sjk-0.10.jar ssa -f node.jfr --histo
Unable to parse file '.\node.jfr'. Parser config: SJK Thread Dump (Magic: TRACEDUMP_1, TRACEDUMP_2), SJK Genereic Event Dump (Magic: EVENTDUMP_1), JStack dump parser
Stream reader error: java.io.IOException: Invalid magic
No data

java -jar sjk-0.9.3.jar ssa -f node.jfr --histo
Trc(%) Frm N Term(%) Frame
8 100% 8 0 0% io.netty.util.concurrent.SingleThreadEventExecutor$5.run(line:858)
8 100% 8 0 0% java.lang.Thread.run(line:748)
7 87% 7 0 0% io.netty.channel.nio.NioEventLoop.run(line:408)
4 50% 4 0 0% sun.nio.ch.SelectorImpl.select(line:97)

Failed to add tools.jar to classpath

Java home points to D:\fuck\jdk1.8 make sure it is not a JRE path
Failed to add tools.jar to classpath
java.lang.ClassNotFoundException: com.sun.tools.attach.VirtualMachine
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.gridkit.lab.jvm.attach.AttachAPI.(AttachAPI.java:45)
at org.gridkit.lab.jvm.attach.AttachManager.(AttachManager.java:73)
at org.gridkit.jvmtool.cmd.ProcListCmd$JPS.run(ProcListCmd.java:74)
at org.gridkit.jvmtool.cli.CommandLauncher.start(Comman

....
but i can't undertand why?

Ttop with java7: IllegalArgumentException: Comparison method violates its general contract

Hi,

I've used latest binary build (2014-09-06).
Got a "comparator violates its general contract method" error with java 1.7.0_51.

xxxx@yyyy:~/files/sjk$ java -jar sjk.jar ttop -p 4523 -n 20 -o CPU

/home/xxxx/files/sjk/sjk.jar
Monitoring threads ...

Unexpected error: java.lang.IllegalArgumentException: Comparison method violates its general contract!

When relaunched with -Djava.util.Arrays.useLegacyMergeSort=true system property - it worked fine.

P.S. Thanks for sharing your production tools with community!

Bundle.properties in the right folder?

# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.

Is this file really in the correct folder?
I ran into a trouble with

Exception in thread "main" java.util.MissingResourceException: Can't find bundle for base name org/netbeans/lib/profiler/heap/Bundle, locale en_US
 	at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1573)
 	at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1396)
 	at java.util.ResourceBundle.getBundle(ResourceBundle.java:782)
 	at org.netbeans.lib.profiler.heap.HprofByteBuffer.readHeader(HprofByteBuffer.java:140)

and if I look into http://central.maven.org/maven2/org/gridkit/jvmtool/hprof-heap/0.10.1/hprof-heap-0.10.1.jar into folder /org/netbeans/lib/profiler/heap I don't see the Bundle.properties file there.
AFAIK, the file should be located in src/main/resources/org/netbeans/lib/profiler/heap instead of src/main/java/org/netbeans/lib/profiler/heap.

Question about GC CPU Utilization

Hi Alexey,

Many thanks for this great tool!

I have a question. I noticed an interesting metric about GC CPU utilization in the output of the 'ttop' tool:

2016-06-29T15:44:56.789+0200 Process summary
process cpu=12.74%
application cpu=10.03% (user=9.55% sys=0.47%)
other: cpu=2.71%
GC cpu=0.05% (young=0.05%, old=0.00%)

Question: is this the actual amount of CPU that is consumed by the JVM GC threads?

If so, I wonder where does it come from. I have seen this metric in GC logs (i.e. Times usr= sys=), is it the same?
Was not aware that it was exposed also via JMX...

Support for JDK9

It looks like JDK9 is not supported?

ava.lang.ClassCastException: java.base/jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to java.base/java.net.URLClassLoader
  at org.gridkit.lab.jvm.attach.AttachAPI.<clinit>(AttachAPI.java:39)
  at org.gridkit.lab.jvm.attach.AttachManager.<clinit>(AttachManager.java:73)
  at org.gridkit.jvmtool.JmxConnectionInfo.getMServer(JmxConnectionInfo.java:72)
  at org.gridkit.jvmtool.cmd.ThreadTopCmd$TTop.run(ThreadTopCmd.java:92)
  at org.gridkit.jvmtool.cli.CommandLauncher.start(CommandLauncher.java:129)
  at org.gridkit.jvmtool.SJK.main(SJK.java:11)
Failed to access MBean server: 22751

It makes sense given the classloader changes in Java 9, but I didn't seen an issue open tracking this, so thought I'd open one so I could subscribe to it. :-) Thanks!

java.rmi.UnmarshalException: error unmarshalling return

Hi,

Thanks for a great program. When I try to use the mxdump feature, I run into this (see the error message at the bottom)

$ java -jar ./scripts/sjk-plus-0.11.jar mxdump -s some-server:30648 
{
  "beans" : [ {
    // (...a lot of data redacted)
    "name" : "Catalina:type=WebResourceRoot,host=localhost,context=/myapp",
    "modelerType" : "org.apache.tomcat.util.modeler.BaseModelMBean",
    "cachingAllowed" : true,
    "stateName" : "STARTED",
    "trackedResources" : "[]",
    "trackLockedFiles" : false,
    "allowLinking" : true
  }, {
    "name" : "Catalina:type=SSLHostConfig,ThreadPool=\"https-openssl-nio-8443\",name=\"_default_\"",
    "modelerType" : "org.apache.tomcat.util.modeler.BaseModelMBean",
    "certificateChainFile" : null,
    "hostName" : "_default_",
    "enabledProtocols" : [ "TLSv1", "TLSv1.2", "SSLv2Hello", "TLSv1.1" ],
    "disableCompression" : true,
    "truststoreType" : "JKS",
    "certificateRevocationListPath" : null,
    "caCertificatePath" : null,
    "configType" : "EITHER",
    "keyManagerAlgorithm" : "SunX509",
    "truststorePassword" : null,
    "certificateKeyAlias" : null,
    "certificateKeystoreType" : "JKS",
    "trustManagerClassName" : null,
    "honorCipherOrder" : null,
    "ciphers" : "HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA",
    "disableSessionTickets" : false,
    "certificateVerificationDepthConfigured" : false,
    "truststoreAlgorithm" : "PKIX",
    "certificateRevocationListFile" : null,
    "enabledCiphers" : [ "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", "TLS_ECDHE_ECDSA_WITH_AES_256_CCM", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_PSK_DHE_WITH_AES_256_CCM_8", "TLS_DHE_PSK_WITH_AES_256_CCM", "TLS_DHE_RSA_WITH_AES_256_CCM_8", "TLS_DHE_RSA_WITH_AES_256_CCM", "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", "TLS_SRP_SHA_WITH_AES_256_CBC_SHA", "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_PSK_WITH_AES_256_CBC_SHA", "TLS_DHE_PSK_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384", "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", "TLS_PSK_WITH_AES_256_CCM_8", "TLS_PSK_WITH_AES_256_CCM", "TLS_PSK_WITH_AES_256_CBC_SHA384", "TLS_PSK_WITH_AES_256_GCM_SHA384", "TLS_PSK_WITH_AES_256_CBC_SHA", "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256", "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", "TLS_ECDHE_ECDSA_WITH_AES_128_CCM", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_PSK_DHE_WITH_AES_128_CCM_8", "TLS_DHE_PSK_WITH_AES_128_CCM", "TLS_DHE_RSA_WITH_AES_128_CCM_8", "TLS_DHE_RSA_WITH_AES_128_CCM", "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", "TLS_SRP_SHA_WITH_AES_128_CBC_SHA", "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_PSK_WITH_AES_128_CBC_SHA", "TLS_DHE_PSK_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256", "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", "TLS_PSK_WITH_AES_128_CCM_8", "TLS_PSK_WITH_AES_128_CCM", "TLS_PSK_WITH_AES_128_CBC_SHA256", "TLS_PSK_WITH_AES_128_GCM_SHA256", "TLS_PSK_WITH_AES_128_CBC_SHA", "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256" ],
    "caCertificateFile" : null,
    "openSslConf" : null,
    "insecureRenegotiation" : false,
    "truststoreProvider" : null,
    "certificateKeyFile" : null,
    "certificateKeystoreFile" : "/var/lib/tomcat8/.keystore",
    "revocationEnabled" : false,
    "certificateKeystoreProvider" : null,
    "sessionCacheSize" : 0,
    "openSslConfContext" : 0,
    "openSslContext" : 140587870744736,
    "certificateKeystorePassword" : "<removed>",
    "objectName" : "Catalina:type=SSLHostConfig,ThreadPool=\"https-openssl-nio-8443\",name=\"_default_\"",
    "sslProtocol" : "TLS",
    "sessionTimeout" : 86400,
    "truststoreFile" : null,
    "certificateFile" : null,
    "certificateVerificationDepth" : 10,
    "certificateKeyPassword" : null
  }, {
    "name" : java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
	java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.apache.coyote.RequestGroupInfo

The process in question is a Tomcat 8 process running on Linux.

Maybe it would be better for SJK to ignore non-serializable objects like org.apache.coyote.RequestGroupInfo? Perhaps logging a message about them if debugging is enabled or something.

Downloads ask for username/password

When I try to download the jar its gives below error

wget https://bit.ly/2H3Uqck -O sjk.jar
--2023-06-14 16:44:24--  https://bit.ly/2H3Uqck
Resolving bit.ly (bit.ly)... 67.199.248.11, 67.199.248.10
Connecting to bit.ly (bit.ly)|67.199.248.11|:443... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.gridkit.jvmtool&a=sjk-plus&v=LATEST [following]
--2023-06-14 16:44:24--  https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.gridkit.jvmtool&a=sjk-plus&v=LATEST
Resolving repository.sonatype.org (repository.sonatype.org)... 54.89.192.189, 34.198.184.168
Connecting to repository.sonatype.org (repository.sonatype.org)|54.89.192.189|:443... connected.
HTTP request sent, awaiting response... 401 Unauthorized

Username/Password Authentication Failed.

Would like to know the username/password for the same

String fix for Java 10 (PR 35)

Hi,

I am using your library in a Java-based OS to find memory leaks automatically.

One small thing. I believe the library is not fully adapted to Java 10? It generally seems to work, don't get me wrong ๐Ÿ‘

The issue I have is with the method org.gridkit.jvmtool.heapdump.HeapWalker.stringValue():

    public static String stringValue(Instance obj) {
        if (obj == null) {
            return null;
        }
        if (!"java.lang.String".equals(obj.getJavaClass().getName())) {
            throw new IllegalArgumentException("Is not a string: " + obj.getInstanceId() + " (" + obj.getJavaClass().getName() + ")");
        }
        char[] text = null;
        int offset = 0;
        int len = -1;
        for(FieldValue f: obj.getFieldValues()) {
            Field ff = f.getField();
            if ("value".equals(ff.getName())) {
                PrimitiveArrayInstance chars = (PrimitiveArrayInstance) ((ObjectFieldValue)f).getInstance();
                text = new char[chars.getLength()];
                for(int i = 0; i != text.length; ++i) {
                    text[i] = ((String)chars.getValues().get(i)).charAt(0);
                }
            }
            // fields below were removed in Java 7
            else if ("offset".equals(ff.getName())) {
                offset = Integer.valueOf(f.getValue());
            }
            else if ("count".equals(ff.getName())) {
                len = Integer.valueOf(f.getValue());
            }
        }

        if (len < 0) {
            len = text.length;
        }

        return new String(text, offset, len);
    }

which clearly is pre-JDK 10 code. Any intention to upgrade this?

Many greetings,
Stefan
BotCompany.de

Edit: In fact, I might just do this myself...

error while trying to access java program

so while trying to use ttop I get a error strange thing is that jps detects it...

thanks
RF

rferreira@graylog1-cab2:~$ sudo java -jar sjk-plus-0.4.2.jar jps
25987   sjk-plus-0.4.2.jar jps
23691   /usr/share/graylog-server/graylog.jar server -f /etc/graylog/server/server.conf -np
rferreira@graylog1-cab2:~$ sudo java -jar sjk-plus-0.4.2.jar ttop -p 23691 -n 20 -o CPU
Failed to access MBean server: 23691

Can't connect to the app

Java: 1.8.0_60-b27
App: tomcat-based single webapp under jsvc

sudo java -jar ~/bin/sjk.jar ttop -p 21787 -n 20 -o CPU

The actual result:
Failed to access MBean server: 21787

In mx command, get multiple attributes

I'd like to be able to use a wildcard

sjk mx -p 12345 -b 'package:name=MBean' -mg -f '*' 

Or a list of attributes

sjk mx -p 12345 -b 'package:name=MBean' -mg -f 'Percentile50,Percentile95' 

Or a matching a regexp

sjk mx -p 12345 -b 'package:name=MBean' -mg -f '.*Percentile.*' 

The result might be:

package:name=MBean
Percentile50 123
Percentile95 234

Instance.getNearestGCRootPointer(): find out which field contains the reference

Hi Alexey!

I find memory leaks automatically in my OS.

However, I can see the instances making up a path to the GC root, but not the field names that link them together. Do I have to find the field name manually or is there an easier way?

Many greetings,
Stefan

Source. Current output without field names:

Checking module ID: #1016442 - System Version

Path to GC root:
  main$JavaXClassLoaderWithParent
    java.lang.Class
      main$SystemVersion
        java.lang.ThreadLocal$ThreadLocalMap$Entry
          java.lang.ThreadLocal$ThreadLocalMap$Entry[]
            java.lang.ThreadLocal$ThreadLocalMap
              main$191$1

Checking module ID: #1016805 - Provoke DeadLock (& have OS solve it) [Dyn Module]

Path to GC root:
  main$JavaXClassLoaderWithParent
    java.security.ProtectionDomain
      java.security.ProtectionDomain[]
        java.security.AccessControlContext
          javax.swing.JButton
            javax.swing.JInternalFrame
              java.lang.Object[]
                java.util.ArrayList
                  main$DesktopPaneWithFitPicture
                    javax.swing.JInternalFrame
                      java.lang.Class

Question about users and PID connection

A given application is running as user foo with PID 12345, it puts its metadata in a folder named /tmp/hsperfdata_foo

By setting the appropriate rights, is it possible for another user bar to run sjk ttop -p 12345. By default, the tool is looking for metadata in /tmp/hsperfdata_bar and doesn't find PID 12345:

Failed to access MBean server: 12345

Does SSA use asyncgetcalltrace or JVMTI getCallTrace to walkthrough Java stack trace

Team,

Thanks for creating this project. The tools developed were really useful particularly ssa with flamegraphs. But we would like to know whether ssa uses asyncgetcalltrace(AGCT) or JVMTI getCallTrace to walkthrough Java stack trace. Since AGCT output would be accurate in walking through stack asynchronously not impacted by safepoint bias.

Sattish.

sjk cannot connect to MBean server with adopt openjdk 11

While using Adopt OpenJDK 11 for the running workload, sjk cannot access MBean server. All jvm are started with sames user. If workload is executed with Oracle JRE 1.8, utility works. In both cases, jmap/jstack application can connect to target JVM (Java11 and 8)

This is the output running AppMain with Adopt OpenJDK 11.
c@localdev:/opt/c/sjk|โ‡’ java -jar sjk-plus-0.11.jar jps 4087 com.net.AppMain 6266 sjk-plus-0.11.jar jps c@localdev:/opt/c/sjk|โ‡’ java -jar sjk-plus-0.11.jar gc -p 4087 Failed to access MBean server: 4087

Instead, running AppMain with Oracle JRE 8, connection happens.

MBean server connected Collecting GC stats ...

OpenJDK pre-build image taken from https://adoptopenjdk.net/.
Tested on CentOS 7 and 6

Add more security to MXPR

it would be nice to add more security tomxpr, for example, ability to specify user name & password for remote connection.

It would be also useful to add SSL, but it could be too much work.

Security Vulnerability - Action Required: XXE vulnerability in the newest version of the jvm-tools

I think your project may be vulnerable to Improper Restriction of XML External Entity Reference. It shares similarities to a recent CVE disclosure CVE-2021-3878 in the stanfordnlp/CoreNLP. The vulnerable methods are as follows:

  1. org.gridkit.jvmtool.hflame.XmlUtil.parse(Reader reader) in the file sjk-hflame/src/main/java/org/gridkit/jvmtool/hflame/XmlUtil.java

The source vulnerability information is as follows:

Vulnerability Detail:
CVE Identifier: CVE-2021-3878
Description: corenlp is vulnerable to Improper Restriction of XML External Entity Reference
Reference:https://nvd.nist.gov/vuln/detail/CVE-2021-3878.
Patch: stanfordnlp/CoreNLP@e5bbe13.

Vulnerability Description:
This vulnerability occurs because of the Improper Restriction of XML External Entity Reference. Given that the XML schema files which is compromised by a hacker, the victim conducts regular process may result in an XML External Entity (XXE) Injection attack.

Recommended Actions:
The corresponding fixes are similar to CVE-2021-3878 to some extent. I have provided the following fixes by applying several patching statements, ensuring that the external entities and DTDs are not loaded when parsing and processing XML documents using the document builder. You can call the function safeDocumentBuilderFactory I defined below instead of directly calling DocumentBuilderFactory.newInstance() to create a DocumentBuilderFactory object to avoid XXE attacks.

  public static DocumentBuilderFactory safeDocumentBuilderFactory() {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
      dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
      dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
      dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
      dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
      dbf.setFeature("http://apache.org/xml/features/dom/create-entity-ref-nodes", false);
      dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
    } catch (ParserConfigurationException e) {
      log.warn(e);
    }
    return dbf;
  }

Considering the potential riskes it may have, I am willing to cooperate with your to verify, address, and report the identified vulnerability promptly through responsible means. If you require any further information or assistance, please do not hesitate to reach out to me.
Thank you and looking forward to hearing from you soon.

Editable JMX connection string

Hello, Alexey.

I have a topic to discuss and JMX connection string customization is a subject.

Recent applications servers, for instance Wildfly, offers JMX connection over http-remoting-jmx.
As jvm-tools has RMI hard coded in the connection string at JmxConnectionInfo.java, a code change has to be made in order to change the connection type.

I need to know your opinion as for customization of a protocol string, mostly designing related question.
final String uri = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi";

Have I to implement customization in one of the preferable ways while using -cp with provider's protocol realization:

  • Override service:jmx:rmi:///jndi/rmi:// with my own hardcoded string service:jmx:remoting-jmx:///jndi/rmi:// while always using WildFly http-jmx interface?
  • Allow for override of JMX protocol string with the property setting via -D flag?
  • Use -s flag value as fully overriding JMX connection string?
  • Add new flag to have a chance to form own JMX connection string?

Please, let me know if I need to issue a pull request.
Thank you for your job!

retained size of objects issue

I'm trying to use your nice library in order to compute the retained size of an object, because I have a huge hprof file.

I used HeapFactory.createHeap(), because I see that getRetainedSize() is not implemeted for FastHprofHeap.

It works, the only thing is that it gives a different result compared with Yourkit or Eclipse Memory Analyzer (those two give the exact same number of bytes each time).

Example

                Map<Integer, String> map = new HashMap<>();
		for (int i = 0; i < numberOfItems; i++) {
			map.put(i, Integer.toString(i));
		}

The bigger the numberOfItems, the bigger the difference in retained size between this api and the standard tools.
E.g
for 5 items, this library returns 730 and Yourkit and EMA return 544
for 10_000 items, this library returns 1,366,404 and Yourkit and EMA return 1,023,568

Any ideas? Thank you!

Unable to parse visualvm nps generated by visualvm 2.0.1

Hi, I ran into issue where sjk seems unable to understand nps format.

VisualVM: v2.0.1
Jdk: v14

Unable to parse file './profiler-snapshot2.nps'. Parser config: SJK Thread Dump (Magic: TRACEDUMP_1, TRACEDUMP_2), SJK Genereic Event Dump (Magic: EVENTDUMP_1), JStack dump parser
Input files
  ./profiler-snapshot2.nps

Unable to parse file './profiler-snapshot2.nps'. Parser config: SJK Thread Dump (Magic: TRACEDUMP_1, TRACEDUMP_2), SJK Genereic Event Dump (Magic: EVENTDUMP_1), JStack dump parser
Stream reader error: java.io.IOException: Invalid magic
java.io.IOException: Invalid magic
	at org.gridkit.jvmtool.stacktrace.MagicReader.readMagic(MagicReader.java:33)
	at org.gridkit.jvmtool.stacktrace.ThreadEventCodec.createEventReader(ThreadEventCodec.java:30)
	at org.gridkit.jvmtool.AbstractEventDumpSource.openReader(AbstractEventDumpSource.java:151)
	at org.gridkit.jvmtool.AbstractThreadDumpSource.openReader(AbstractThreadDumpSource.java:119)
	at org.gridkit.jvmtool.AbstractEventDumpSource$1.produceNext(AbstractEventDumpSource.java:128)
	at org.gridkit.jvmtool.event.ChainedEventReader.hasNext(ChainedEventReader.java:68)
	at org.gridkit.jvmtool.event.ShieldedEventReader.seekNext(ShieldedEventReader.java:66)
	at org.gridkit.jvmtool.event.ShieldedEventReader.hasNext(ShieldedEventReader.java:95)
	at org.gridkit.jvmtool.event.ShieldedEventReader.seekNext(ShieldedEventReader.java:66)
	at org.gridkit.jvmtool.event.ShieldedEventReader.hasNext(ShieldedEventReader.java:95)
	at org.gridkit.jvmtool.event.MorphingEventReader.hasNext(MorphingEventReader.java:33)
	at org.gridkit.jvmtool.hflame.JsonFlameDataSet.feed(JsonFlameDataSet.java:97)
	at org.gridkit.jvmtool.hflame.cmd.FlameGraphGeneratorCmd$FlameGen.run(FlameGraphGeneratorCmd.java:100)
	at org.gridkit.jvmtool.cli.CommandLauncher.start(CommandLauncher.java:134)
	at org.gridkit.jvmtool.SJK.main(SJK.java:14)
0 samples processed
No data omit report generation```

Wrong usage of Java home

When calling the program, e.g.

 java -jar sjk.jar hh -p 12556

the first output is:

Java home points to C:\Program Files\Java\jre1.8.0_202 make sure it is not a JRE path

However, my JAVA_HOME variable is set as follows (result of set JAVA_HOME):

JAVA_HOME=C:\Program Files\Java\jdk1.8.0_202

So apparently the tool uses some other Java home, which I don't know how to change. I'd suggest to use the value of the JAVA_HOME environment variable instead. Currently I am unable to use the tool at all.

I downloaded the newest version using wget https://bit.ly/2H3Uqck -O sjk.jar. My OS is Microsoft Windows 10 Pro (Version: 10.0.19042 Build 19042) and I tried cmd and Powershell. Please let me know if you need any further information.

Inconsistent library versions notice.

Hi. I have implemented a tool to detect library version inconsistencies. Your project have 3 inconsistent libraries.

Take org.gridkit.lab:jvm-attach-api for example, this library is declared as version 1.5 in hprof-heap, 1.2 in bstub and etc... Such version inconsistencies may cause unnecessary maintenance effort in the long run. For example, if two modules become inter-dependent, library version conflict may happen. It has already become a common issue and hinders development progress. Thus a version harmonization is necessary.

Provided we applied a version harmonization, I calculated the cost it may have to harmonize to all upper versions including an up-to-date one. The cost refers to POM config changes and API invocation changes. Take org.gridkit.lab:jvm-attach-api for example, if we harmonize all the library versions into 1.5. The concern is, how much should the project code adapt to the newer library version. We list an effort table to quantify the harmonization cost.

The effort table is listed below. It shows the overall harmonization effort by modules. The columns represents the number of library APIs and API calls(NA,NAC), deleted APIs and API calls(NDA,NDAC) as well as modified API and API calls(NMA,NMAC). Modified APIs refers to those APIs whose call graph is not the same as previous version. Take the first row for example, if upgrading the library into version 1.5. Given that 6 APIs is used in module sjk-core, 0 of them is deleted in a recommended version(which will throw a NoMethodFoundError unless re-compiling the project), 0 of them is regarded as modified which could break the former API contract.

Index Module NA(NAC) NDA(NDAC) NMA(NMAC)
1 sjk-core 6(8) 0(0) 0(0)
2 hprof-heap 1(1) 0(0) 0(0)
3 bstub 0(0) 0(0) 0(0)

Also we provided another table to show the potential files that may be affected due to library API change, which could help to spot the concerned API usage and rerun the test cases.

If you are interested, you can have a more complete and detailed report in the attached PDF file.
aragozin jvm-tools.pdf

Add documentation about connecting to JVMs

As a newcomer, I wish I had read some advice to troubleshoot connection between sjk and my app:

$ java -jar sjk.jar ttop -p <pid>
Failed to access MBean server: <pid>
  • Always use the same user to run sjk as the application: sudo -u elasticsearch java -jar sjk.jar ttop -p <elasticsearch pid> and test the connection with jstack before using sjk
  • Disable firewalls (iptables and the like): even if you're connecting locally using a PID, sockets are still used for communication.

This would have saved me hours of investigation.

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.