Can I open custom hsperfdata_root/PID after process shutdown? - java

I'm using docker to containerize my application and want to look at it's performance from host machine. I've mapped volume : "/opt/tmp/my_app/:/tmp", which contains hsperfdata_root
Can I somehow open heap and other information from that hsperfdata_root/PID in jmap or some other tool ?
Does container must be in Running state for such debugging or it might be shutdown ?

The JDK includes the jstat tool for doing this. Try jstat -snap file:/tmp/hsperfdata_root.

Related

Get GC log data from the Docker container using jstat

I have a java application running inside a docker container with OpenJDK11. I want to get GC data from this application using jstat tool (available inside a container). Any idea how can I achieve this from the host or another container running on the same host?
Thank you :)
The processes are visible on the host, so jstat -gcstat <pid> works on the host if you know the pid as it is seen by the host.
You can get the host-pid of a container-pid-1 via docker inspect -f '{{.State.Pid}}' <container name> and then walk the process tree (e.g. via /proc or some library encapsulating that logic) to find the java child process and then call jstat.
Another option is to (partially) join the container's namespace via nsenter or docker exec and then just execute jps and jstat inside the container. But that can be a security concern if you don't trust the container.

Profiling tomcat application with VisualVM

I am trying to run visualvm under the username tomcat6 because apparently visualvm can only find applications running under its username. So by default it is only finding applications running under my username. I have been able to connect visualvm with tomcat6 through jmx but that lacks the fine granularity of instrumented profiling.
I tried the following to run visualvm under the username tomcat6 but got the following error that I don't understand.
$ sudo -u tomcat6 jvisualvm
No protocol specified
Exception in thread "main" java.awt.AWTError: Can't connect to X11 window server using ':0' as the value of the DISPLAY variable.
at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
at sun.awt.X11GraphicsEnvironment.access$200(X11GraphicsEnvironment.java:65)
at sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:115)
...
If the computer running your application is remote -- like a server -- then you can't run GUI applications without some work. It's probably going to be easier to enable remote access to VisualVM.
You can use two techniques to attach to a remote JVM: using jstatd or using JMX. I'm not sure what you think you are losing by using JMX, but evidently jstatd doesn't give you access to profiling tools, CPU monitor, etc.).
You need to configure your JVM and Tomcat to allow for remote access. That requires 3 steps:
Enable remote JMX. Turns out, there's a guide for that.
Fix the "wandering port" used for RMI. There's a guide for that, too.
(Optional) Arrange for secure remote-access to the server. The easiest way to do that would be to use ssh -Lport:localhost:port with a series of -L arguments to forward multiple ports from your workstation to your server. Map all the ports you had to configure in steps #1 and #2. If you don't do this, you'll need to have non-firewalled access to all the aforementioned ports.
Restart your JVM and connect with JVisualVM.
Update 2022-06-01
Note that the "wandering port" problem has been fixed at the JVM level, so there is no need for application (i.e. Tomcat) support for that. Item #1 for Tomcat 8.5 and later contains updated instructions making item #2 unnecessary with a recent JVM.
Unfortunately only sampling is available in remote mode so JMX will lack instrumentation tools.
Actually your approach to running visualvm under tomcat6 user is correct. You should take a look at this question on how to run X11 applications under sudo.
The easiest way to pass DISPLAY and XAUTHORITY environment variables is to use sudo -E command to preserve current user environment.
Also if you can't see your process under tomcat6 user you should check if CATALINA_TMPDIR is pointing to /tmp. Otherwise you should pass it to visualvm
jvisualvm -J-Djava.io.tmpdir="${CATALINA_TMPDIR}"
Actually there is a lot of alternatives like yourkit or jprofiler shipped with java agents which allows remote instrumentation profiling.
The easiest is to open a remote JXM port on Tomcat in order to be able to remotely (from your desktop computer) connect to your remote Tomcat (on your server) with jvisualvm.
You need to pass the following system properties to your JVM :
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=<whatever_port_you_want>
-Dcom.sun.management.jmxremote.ssl=false
Then open jvisualvm on your local computer (JVM version needs to be the same or newer), File -> Add Remote Host -> Enter the name on the Host. It will create an entry for this host. Right lick on this Entry -> Add JMX connection -> Enter the port -> OK
jvisualvm will then be able to access remotely to your application.
You can also secure the connection if needed by using the following system properties (you need to create the files and locate them where you want :
-Dcom.sun.management.jmxremote.password.file=jmxremote.password
-Dcom.sun.management.jmxremote.access.file=jmxremote.access
These properties needs to be added to the CATALINA_OPTS environment variable. Fr exemple :
export CATALINA_OPTS = "$CATALINA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8888 "
More info on JMX lies here : https://docs.oracle.com/javase/8/docs/technotes/guides/management/agent.html
I tried to do something similar but I was not allowed to install JVisualVM on the server. Having JVisualVM connect to the remote machine never seemed to work correctly. I suspect firewall rules were blocking part of the the network connections.
The only way I found to remotely profile the server was via an ssh tunnel.
Set the JMX port in CATALINA_OPTS on the server
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.port=13333 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false; export CATALINA_OPTS
On your desktop machine open an ssh connection to the server
ssh -D 61444 username#tomcat.server.address
Add a flag to JVisualVM so that it will proxy its network connection
"C:\Program Files\Java\jdk1.7.0_79\bin\jvisualvm.exe" -J-Dnetbeans.system_socks_proxy=localhost:61444 -J-Djava.net.useSystemProxies=true
Have JVisualVM connect to the jmxport and the network traffic is tunneled via ssh.
Good luck.

GET Tomcat java maximum memory pool size using cmd or PowerShell

i have several Tomcat 6,7,8 servers and i would like to run a PowerShell script to get me the Maximum memory pool size of its JAVA Jvm options, is there a way to get it ?
thanks.
Take a look at jvmtop. It is a command line tool to fetch information from locally running JVM's.
If you have remote servers then you probably need to active JMX on the servers and write your own code. See Can jconsole data be retrieved from the command line?

Why can't I attach jvisualvm to an instance of tomcat started from inside osx?

I'm starting tomcat from inside netbeans. I'd like to monitor the heap usage on that instance of tomcat so I fire up jVisualVM. However the process isn't listed. Any ideas?
Are you using Java version 6u24? Then you may fall victim to this bug which will be fixed in 6u25 (in a nutshell, jVisualVM can't find your process' hsperfdata).
Otherwise, you have to enable monitoring via JMX:
Pass the following JVM parameters to Tomcat:
-Dcom.sun.management.jmxremote.port=8888 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
Then add the remote process to jVisualVM via File -> Add JMX Connection. You can connect to the process using port 8888
jVisualVM has some other gotchas, e.g. the user starting jVisualVM needs to be the same as the user owning the process you want to monitor (although, I don't think this is your issue). See more here.

Monitor JVM on tomcat service

Hi I noticed that different tools for monitoring JVM require that the process will be java.exe in the taskbar. Its process id is supplied to them and then statistics regarding garbage collection and etc are returned. When running tomcat as a service, there is no a process named jave.exe but it is tomcat6.exe.
How can I get statistics regarding the JVM tomcat6 uses ?
Enable JMX in Tomcat and then connect via JConsole or JVisualVM. The name of the process is not relevant.

Categories