Getting the parameters of a running JVM - java

Is there a way to get the parameters of a running JVM?
Is there a command-line tool, like jstat, which takes as input the PID of the JVM and returns its starting parameters? I am particularly interested in the -Xmx and -Xms values that were given when starting the JVM.
To clarify my constraints for the JVM, we would like to check if it is running on a production server. That's why we prefer the minimum disruption. We are able to monitor the JVM using jstat, and so we hope there's a similar simple solution to access the parameters.
We also tried to get the parameters using jvisualvm. But in order to connect to a remote jvm, we need to run jstatd and modify the security settings of the JVM, which we found to be very disruptive and risky on a production server.

You can use jps like:
jps -lvm
It prints something like:
4050 com.intellij.idea.Main -Xms128m -Xmx512m -XX:MaxPermSize=250m -ea -Xbootclasspath/a:../lib/boot.jar -Djb.restart.code=88
4667 sun.tools.jps.Jps -lvm -Dapplication.home=/opt/java/jdk1.6.0_22 -Xms8m

As per JDK 8 documentation jcmd is the suggested approach.
It is suggested to use the latest utility, jcmd instead of the
previous jstack, jinfo, and jmap utilities for enhanced diagnostics
and reduced performance overhead.
Below are commands to get your properties/flags you want.
jcmd pid VM.system_properties
jcmd pid VM.flags
We need the PID. For this, use jcmd -l, like below
cd ~/javacode
jcmd -l
11441 Test
6294 Test
29197 jdk.jcmd/sun.tools.jcmd.JCmd -l
Now it is time to use these PIDs to get properties/flags you want.
Command: jcmd 11441 VM.system_properties
11441:
#Tue Oct 17 12:44:50 IST 2017
gopherProxySet=false
awt.toolkit=sun.lwawt.macosx.LWCToolkit
file.encoding.pkg=sun.io
java.specification.version=9
sun.cpu.isalist=
sun.jnu.encoding=UTF-8
java.class.path=.
java.vm.vendor=Oracle Corporation
sun.arch.data.model=64
java.vendor.url=http\://java.oracle.com/
user.timezone=Asia/Kolkata
java.vm.specification.version=9
os.name=Mac OS X
sun.java.launcher=SUN_STANDARD
user.country=US
sun.boot.library.path=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/lib
sun.java.command=Test
http.nonProxyHosts=local|*.local|169.254/16|*.169.254/16
jdk.debug=release
sun.cpu.endian=little
user.home=/Users/XXXX
user.language=en
java.specification.vendor=Oracle Corporation
java.home=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home
file.separator=/
java.vm.compressedOopsMode=Zero based
line.separator=\n
java.specification.name=Java Platform API Specification
java.vm.specification.vendor=Oracle Corporation
java.awt.graphicsenv=sun.awt.CGraphicsEnvironment
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
ftp.nonProxyHosts=local|*.local|169.254/16|*.169.254/16
java.runtime.version=9+181
user.name=XXXX
path.separator=\:
os.version=10.12.6
java.runtime.name=Java(TM) SE Runtime Environment
file.encoding=UTF-8
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
java.vendor.url.bug=http\://bugreport.java.com/bugreport/
java.io.tmpdir=/var/folders/dm/gd6lc90d0hg220lzw_m7krr00000gn/T/
java.version=9
user.dir=/Users/XXXX/javacode
os.arch=x86_64
java.vm.specification.name=Java Virtual Machine Specification
java.awt.printerjob=sun.lwawt.macosx.CPrinterJob
sun.os.patch.level=unknown
MyParam=2
java.library.path=/Users/XXXX/Library/Java/Extensions\:/Library/Java/Extensions\:/Network/Library/Java/Extensions\:/System/Library/Java/Extensions\:/usr/lib/java\:.
java.vm.info=mixed mode
java.vendor=Oracle Corporation
java.vm.version=9+181
sun.io.unicode.encoding=UnicodeBig
java.class.version=53.0
socksNonProxyHosts=local|*.local|169.254/16|*.169.254/16
Command: jcmd 11441 VM.flags output:
11441:
-XX:CICompilerCount=3 -XX:ConcGCThreads=1 -XX:G1ConcRefinementThreads=4 -XX:G1HeapRegionSize=1048576 -XX:InitialHeapSize=67108864 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=1073741824 -XX:MaxNewSize=643825664 -XX:MinHeapDeltaBytes=1048576 -XX:NonNMethodCodeHeapSize=5830092 -XX:NonProfiledCodeHeapSize=122914074 -XX:ProfiledCodeHeapSize=122914074 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:-UseAOT -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC
For more instructions of usages of jcmd, see my blog post.

On Linux:
java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'
On Mac OS X:
java -XX:+PrintFlagsFinal -version | grep -iE 'heapsize|permsize|threadstacksize'
On Windows:
java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"
Source: Find out your Java heap memory size

Alternatively, you can use jinfo
jinfo -flags <vmid>
jinfo -sysprops <vmid>

If you can do this in Java, try:
RuntimeMXBean
ManagementFactory
Example:
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
List<String> jvmArgs = runtimeMXBean.getInputArguments();
for (String arg : jvmArgs) {
System.out.println(arg);
}

On Linux, you can run this command and see the result:
ps aux | grep "java"

JConsole can do it. Also you can use the powerful Java VisualVM tool, which also is included in JDK since 1.6.0.8.

Windows 10 or Windows Server 2016 provide such information in their standard Task Manager.
It is a rare case for production, but if the target JVM is running on Windows, the simplest way to see its parameters is to press Ctrl + Alt + Delete, choose the Processes tab and add the Command line column (by clicking the right mouse button on any existing column header).

In case of really small containers (no ps, tree, jcmd etc.) you can also try to guess process id (by listing ls -l /proc) and then read parameters from specific process:
cat /proc/<pid>/cmdline.
example:
$ cat /proc/614/cmdline
may print something like:
java-D[Standalone]-server-Xms64m-Xmx512m-XX:MetaspaceSize=96M-XX:MaxMetaspaceSize=256m-Djava.net.preferIPv4Stack=true-Djboss.modules.system.pkgs=org.jboss.byteman-Djava.awt.headless=true-Dkeycloak.profile=preview-Djboss.as.management.blocking.timeout=1800-Djboss.node.name=keycloak1loak/modulesorg.jboss.as.standalone
To read the same for all processes (discarding any permission errors and processes that dissapeared during command execution):
for i in $(find /proc/ -maxdepth 2 -type f -name cmdline -exec ls {} 2>/dev/null \; ); do echo "$i"; cat $i 2>/dev/null; echo; echo; done
Note: It's not narrowed down to java processes only - you can do that using grep.

If you are interested in getting the JVM parameters of a running Java process, then just do kill -3 java-pid.
You will get a core dump file in which you can find the JVM parameters used while launching the Java application.

You can use the JConsole command (or any other JMX client) to access that information.

_JAVA_OPTIONS is an environment variable that can be expanded:
echo $_JAVA_OPTIONS

This technique applies for any Java applications running local or remote.
Start your Java application.
Run Java VisualVM found in you JDK (such as C:\Program
Files\Java\jdk1.8.0_05\bin\jvisualvm.exe).
When this useful tool starts look at the list of running Java applications under the
"Local" tree node.
Double click [your application] (pid [n]).
On the right side, there will be inspection contents in a tab for the
application. In the middle of the Overview tab, you will see the JVM arguments for the application.
Java VisualVM can be found in any JDK since JDK 6 Update 7. Video tutorial on Java VisualVM is here.

I usually do ps -ef | grep java. It outputs the process with PID + the used command line parameters.

Related

How to find out default jvm options when you start jar

How can i find out default options of a jvm when i start some jar file ? Except those options, which are specified in a command, like java -jar somefile.jar -XX:MaxPermSize=256m. So, what i need to know is there any other hided options of a jvm which i can find ?
One of the way to do that is to search for a java process by running
ps -ef | grep java
which will show you all the JVM params.
Note: this will work only on Linux and probably MacOS

Why the JDK's jps command does not list the process of JBoss instance?

I am currently using JBoss at work to run some Java web application in Linux. The running instance of JBoss is listed with the process list command ps aux |grep java, and the relevant output is something like jboss 19622 0.3 35.8 3410688 1391068 ? Sl Dec13 3:27 /opt/wsp/jdk1.8.0/bin/java -D[Standalone] -server -XX:+UseCompressedOops -Xms1024m -Xmx1024m -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true...
According to my understanding, there should be corresponding JVMs listed by using JDK's command jps. But when I typed jps in terminal, only one record is listed, something like 12073 jps. I am pretty confused about why is it like that, anyone can explain? Thanks in advance!
The reason is that jBoss is run by a different user. ps aux shows every process of the system, while jps is restricted by permissions of the user running the command.

setting option for JVM

I'm kinda lost in the java-options world
I've got a server and I'm doing some research for tuning issue
I found some options that I want to set for my jvm used by Tomcat
(ie Xmx, Xms)
where have I got to put thoswe settings? in setenv?
I tryed:
Export JAVA_OPTS="$JAVA_OPTS -server -Xmx512m -Xms512m"
then restart Tomcat and
java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize'
gave me (like before)
uintx MaxHeapSize := 1035993088
I think I missed something
Plus I've got 64bit system and 8GB RAM, accrding to my research I found that I can set Xmx to 6GB, but none information about Xms. Any advice? thank you all
The second "java" command has nothing to do with your running Tomcat! This starts just a second JVM.
If you want to see the arguments with which your Tomcat JVM was actually started, then on Linux use ps eww -p <pid> or pargs <pid> on Solaris.
Btw, CATALINA_OPTS is prefered over JAVA_OPTS, the latter one is used for all Java processes started by the tomcat Installation, and CATALINA_OPTS only for the main server process.

How to retrieve Java vendor information

How can I retrieve Java vendor information without having to compile and run following script:
import java.util.Properties;
public class test
{
public static void main(String args[])
{
Properties prop = System.getProperties();
System.out.println ("JVM Vendor : " + prop.getProperty("java.vendor") );
}
}
I couldn't find it in command line options.
Note: The following will work for the Oracle JVM - not tested on others. (To get details on non-standard options execute java -X)
You can use the non-standard -XshowSettings flag to show all settings, or alternatively -XshowSettings:properties to show all property settings.
So for example if you execute the following command:
java -XshowSettings:properties -version
This will show you all properties one of which is java.vendor. Not sure if it is possible to get it to output just a single property though.
If you have any running java app 'jinfo' is your friend:
Usage:
jinfo [option] <pid>
(to connect to running process)
jinfo [option] <executable <core>
(to connect to a core file)
jinfo [option] [server_id#]<remote server IP or hostname>
(to connect to remote debug server)
where <option> is one of:
-flag <name> to print the value of the named VM flag
-flag [+|-]<name> to enable or disable the named VM flag
-flag <name>=<value> to set the named VM flag to the given value
-flags to print VM flags
-sysprops to print Java system properties
<no option> to print both of the above
-h | -help to print this help message
So
jinfo -sysprops <pid of javaprocess> | grep "java.vendor = "
gives you the system property.
Beware:
Also note that the value of system properties can be overwritten! For example, if myProperties.txt contains the following line, the java.vendor system property will be overwritten:
java.vendor=Acme Software Company
You may use below command
$ java -XshowSettings:properties -version
Below is good blog on JAVA properties for Linux and Windows
Retrieve JAVA properties & Version information
If it's JDK run jvisualvm, open VisualVM app, go to "System properties" tab
if it's Tomcat goto: TOMCAT_HOME/bin/
and then execute the version.sh file (*e.g. ./version.sh).

How to redirect the "kill -3 <jvm pid>" stdout to a file singly in linux and unix?

I start up a jvm process on a linux platform, like tomcat web container.
start up command-line :
nohup sh > nohup.out 2>&1 &
When i take a "kill -3 " command, the thread dump information will output to the nohup.out file.
How can i redirect the output to a file singly ?
The Sun HotSpot JVM it's own toolkit from jdk 1.5 which is called jstack, it's very useful by using Sun HotSpot JVM, but the JRockit JVM and HP HotSpot JVM, IBM J9 VM are unsuited.
How can wirte a good generality toolkit to redirect the thread dump information to a single file, and not be stdout file ?
It is part of the standard unix process protection policy that after the start of a program no more redirections for its streams can be done without the active help of that program.
But if you don't care that the threaddump is still in nohup.out and additionally in some other file you can do it like this:
tail -f nohup.out > my_new_threaddump &
kill -3 $pid_target_process
kill %+
Of interest is the related kill -3 to get java thread dump, including Vadzim answer:
-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=jvm.log
However, this isn't (or at least didn't use to be) compatible with JRockit etc - e.g. see http://blog.eisele.net/2011/01/running-glassfish-with-jrockit.html

Categories

Resources