I have a running jvm process and I want a tool to get classes loaded by that jvm, are there one?
You can use jmap -histo <PID>
It'll show histogram of loaded classes including classname, number of instances, size, etc
jinfo <pid>
will give you quite a bit information, including the classpath and the jars in the path.
see here
The jinfo command may be limited by the permissions granted to the principal running the command. The command will only list the JVMs for which the principle has access rights as determined by operating system specific access control mechanisms.
Note also that jinfo is not available on windows or linux itanium.
You can use the following in the command line
java -verbose:class ....
and the JVM will dump out what it's loading including all its locations
try visual VM. It is free but is not distributed with JRE/JDK but you can download it from official oracle website. Also you can make a heap dump and than you can view it by standard tools from JDK.
If the process has JMX enabled then you can use jvisualvm (bundled with the JDK) to examine such properties.
Related
I restarted a Java process with new memory options -Xms4G -Xmx4G -XX:MaxDirectMemorySize=6G and wanted to verify if these changes got correctly applied, especially the 6G of direct memory.
The first solution I found for verifying this was via java itself, but this simply reported a 0, implying that my new settings had no effect:
bash-4.4$ java -XX:+PrintFlagsFinal -version | grep MaxDirect
uintx MaxDirectMemorySize = 0 {product}
openjdk version "1.8.0_242"
OpenJDK Runtime Environment (build 1.8.0_242-b08)
OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)
A second solution I found later was via jinfo, which apparently confirm the 6G that I indended to set:
bash-4.4$ jinfo -flag MaxDirectMemorySize 1
-XX:MaxDirectMemorySize=6442450944
I've relied on the java -XX:+PrintFlagsFinal for other purposes before, but now I wonder why it doesn't return the expected values. Why are java and jinfo returning different results?
There's (at least) two different JVMs.
[Expanding comment:] java {nothing} -XX:+PrintFlagsFinal -version creates a new JVM, changes none of its configuration from the default, and prints the resulting configuration, which is the default configuration with no changes -- and the default for MaxDirectMemSize is indeed zero.
OTOH jinfo {option} pid attaches to an existing already running JVM and obtains or changes the configuration of that JVM (although the specific pid 1 isn't usually a JVM but it often is in a docker container as you are using). jps lists the running JVMs you can attach to, with options to include JVM arguments and/or application arguments.
Does this imply that the same verification cannot be achieved with java? Unlike jinfo it cannot be attached to a running JVM?
Yes and no; it gets a bit Wonderlandy.
java by itself creates a new JVM, separate from any existing one. Normally this JVM runs a user-specified program, but with -version as you used it just prints version info and exits without running anything.
Now, the attach API is accessible from (and actually written partly in) Java. What jinfo does in more detail is:
create a new JVM; this doesn't use the java executable, so it isn't easily visible, but it actually is a JVM just like one from java
use that JVM to run some predefined Java code, which used to be in JDK/lib/tools.jar; I haven't bothered to track down where it is (and exactly how to access it) in the new post-8 modulated Java
that Java code when run in the jinfo JVM attaches to, and accesses information in, the specified other JVM, which was previously created and configured with java -Xvarious to run your application
You can actually do steps 2 and 3 yourself; you could write Java code that uses the API to attach to a specified (or otherwise located) existing JVM and get the info you want, and use java to run in JVM#2 your code that accesses info in existing JVM#1. But why bother, when jinfo (and jstat jmap jconsole etc) already does what is needed?
For that matter, jps also does this -- it runs its own JVM to run Java 'tool' code that uses the attach API to list JVMs. That's why the list produced by jps, unless filtered, includes jps itself. In fact, if you could run jps during the very short time jinfo is running, the jps list would include jinfo also -- and if you could determine the pid for jps and run jinfo on that pid during the very short time jps is running, you could get jinfo-type information on the jps JVM.
Clear enough?
I found Tool for analyzing java core dump, which is really close, but when I open up jvisualvm and open "File" menu, the "Add VM Coredump" option is not available. When I run the other option listed in the overflow article I don't get a thread dump. I'm digging into the jmap command a little farther, but I'd like to know how to use the Add VM Coredump feature as it would make life a bit easier.
You must be on Solaris or Linux to access the VisualVM Coredumps option.
In the documentation (http://visualvm.java.net/coredumps.html) it says:
The Core Dump node is visible in the Applications window if VisualVM is running on Solaris or Linux. Generally, VisualVM can only open a core dump if the core dump was taken on the same machine. A core dump contains informaton on the Java Development Kit (JDK) and kernel of the machine where the core dump was taken. To open the core dump in VisualVM, this information must match the JDK software and kernel of the local system.
Now that OSX Maverick works with memory different (so it seems and from what I've read), when I run Java as a separate JVM (Ant/JUnit/etc.), I often get OutOfMemory exceptions as it bases the max heap on memory available which is usually close to zero (because that's apparently how Maverick works?). I know I can set the max heap space using the -Xmx argument for a run or external tool configuration in Eclipse, but that is a pain when I have several possible configurations that can be run.
I believe I would have to run in a separate JVM so my configurations don't get polluted with Eclipse classpath JARs and to a smaller extent, so the Eclipse JVM doesn't get polluted with configuration runs and all the class loading that goes on.
Is there a global setting to set the max heap available for all JVMs launched by Eclipse? For Ant, I tried setting ANT_OPTS in my environement to "-Xm1024m", but that setting doesn't seem to take when running Ant through Eclipse. If I run Ant from the command line directly, it does seem to work (or at least I didn't get an exception). When running Ant in verbose+debug mode in Eclipse, I do see "Setting project property: env.ANT_OPTS -> -Xmx1024m" so I know the variable is set.
I ran Java VisualVM to get a better idea what is going on, this is what it has:
JVM: Java HotSpot(TM) 64-Bit Server VM (23.25-b01, mixed mode)
Java: version 1.7.0_25, vendor Oracle Corporation
Java Home: /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre
JVM Flags: <none>
Main class: org.eclipse.ant.internal.launching.remote.InternalAntRunner
You can configure JVM arguments for an Eclipse Ant build in the Run > External Tools > External Tools Configurations dialog in the JRE tab.
Note that the default is actually to run Ant in the same JVM as Eclipse (which makes some additional Eclipse tasks available).
Running VisualVM made me realize Eclipse was still using 1.7.0_25 and not 1.7.0_45 which is the latest I have installed. Once I updated Eclipse to use 1.7.0_45, I no longer have the issue as the VM does indeed use 1/4 of total memory. Would be nice to know for sure, but it seems like build 25 had a bug or something.
How can I trigger a heap dump for a Java 7 VM running on Linux without having a JDK installed?
In earlier versions of Java it was possible to set the -XX:+HeapDumpOnCtrlBreak JVM option and then trigger a heap dump by using kill -QUIT <pid>. I have been unable to get this to work with Java 7. Is there an equivalent to this without needing the JDK installed to get JVisualVM or jmap.
VM option -XX:+HeapDumpOnCtrlBreak is no longer listed at http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html. So, I conclude that it's no longer supported.
From http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html:
Options that are specified with -XX are not stable and are subject to
change without notice.
You can generate a core dump with gcore, move it to another machine, and attach jmap to generate hprof file as described in Core dump taken with gcore, jmap conversion to hprof file format fails with Error message
See also accepted answer.
According to documentation one could automatically take a heap dump when the application encounters an OutOfMemoryException.
After OutOfMemoryException process just disappear from left menu.
How does this feature works in VisualVM?
Thanks.
C:\work\temp>java -XX:HeapDumpPath=c:/work/temp/file.hprof -XX:+HeapDumpOnOutOfMemoryError -jar example.jar
As far as I know, that option in JVisualVM is equivalent to specifying -XX:+HeapDumpOnOutOfMemoryError as a JVM parameter. This causes the JVM to create a heap dump file when it encounters an OutOfMemoryError. This file can be then loaded into JVisualVM (or into a profiler) and analyzed there. The directory where the file is stored is defined by the -XX:HeapDumpPath parameter.
See also:
Troubleshooting Guide for Java SE 6 with HotSpot VM
Java HotSpot VM Options
StackOverflow: Using HeapDumpOnOutOfMemoryError parameter
Seems application just exited upon OOM. In this case, you must run your app with special -XX params. See "dump" params in JVM documentation. After application dies, you can examine dump in your tool.