VisualVM - Cannot take heap dump - java

When I click on the Heap Dump button in VisualVM 1.3.8, I get the following error:
Cannot take heap dump for user#localhost:9090
Am I missing a setting somewhere?
Edit #1
Environment is:
RHEL6
Tomcat 7.0.68
Java 1.7.0_45
Options are:
export CATALINA_OPTS="-Dcom.sun.management.jmxremote=true\
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=true \
-Djava.rmi.server.hostname=x.x.x.x \
-Dcom.sun.management.jmxremote.password.file=/file_to_pwd \
-Dcom.sun.management.jmxremote.access.file=/file_to_access \
-Xms1256m \
-Xmx1256m \
-XX:PermSize=768m \
-XX:MaxPermSize=768m \
-XX:+CMSClassUnloadingEnabled \
-Dfile.encoding=UTF-8 \
-XX:+CMSClassUnloadingEnabled \
-XX:+UseConcMarkSweepGC \
-server"
Edit #2
Here is the listener for JMX.
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="9090" rmiServerPortPlatform="9091" />

Here's what I ended up doing. We had JDK 1.8 also present on the server.
cd /path/to/java/jdk1.8.0_65/
./jmap -dump:format=b,file=/path/to/dump/tomcat_dump.bin PID
Open /path/to/dump/tomcat_dump.bin using VisualVM (I had to use Filezilla to bring it to my workstation).

One possible reason is permission issue. In Windows right click on the jvisualvm executable and run as administrator solves this issue.

Related

When using Idea to remotely debug a project under Jetty, the prompt is :timeout during handshake

I am using Remote JVM Debug in IDEA to remotely debug my jetty project on the server with the following prompt:timeout during handshake
2021-12-20T03:14:04.816059981Z Listening for transport dt_socket at address: 16005
2021-12-20T03:14:05.755978464Z 2021-12-20 11:14:05.752:INFO::main: Logging initialized #1042ms to org.eclipse.jetty.util.log.StdErrLog
2021-12-20T03:14:05.866523012Z 2021-12-20 11:14:05.865:INFO:oeju.TypeUtil:main: JVM Runtime does not support Modules
2021-12-20T03:14:06.184914262Z 2021-12-20 11:14:06.184:INFO::main: Console stderr/stdout captured to /hostfiles/logs/2021_12_20.jetty.log
2021-12-20T03:20:02.669027944Z Debugger failed to attach: timeout during handshake
The startup configuration is as follows:
java -server \
-Xmx3550m \
-Xms3550m \
-Xmn1256m \
-Xss228k \
-Xdebug \
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=16005 \
-XX:SurvivorRatio=6 \
-XX:MaxMetaspaceSize=256m \
-XX:ParallelGCThreads=8 \
-XX:MaxTenuringThreshold=0 \
-XX:+UseConcMarkSweepGC \
-jar $JETTY_HOME/start.jar \
jetty.base=/hostfiles
Jetty is in Docker, using jdk 1.8, with the following preset parameters:
The current problem is caused by the fact that the forked JVM in Jetty is not configured efficiently.
See https://github.com/eclipse/jetty.project/issues/7299

systemd for java process issue with heap dump

My application is written in java spring boot, to run the application on linux system i have written a systemd file as below.
[Unit]
Description=Service Module For microservice Service.
After=network.target auditd.service
[Install]
WantedBy=multi-user.target
[Service]
Type=idle
Environment=service_name=/home/ec2-user/test-1.0-SNAPSHOT.jar
Environment=env=dev
ExecStart=/usr/bin/java -jar ${service_name} \
--spring.profiles.active=${env} \
--Xmx=1300M \
-XX:+HeapDumpOnOutOfMemoryError \
-Xloggc:gc.log \
-XX:+PrintGCDetails \
-XX:+PrintGCTimeStamps \
-XX:+UseGCLogFileRotation \
-XX:NumberOfGCLogFiles=5 \
-XX:GCLogFileSize=10M
ExecStop=/bin/kill -s TERM $MAINPID
LimitNOFILE=30000
Restart=always
RestartSec=500
StartLimitBurst=3
StartLimitInterval=120
MemoryLimit=1300M
[Manager]
When this systemd file is started, i can see in process mentioned process is running as expected.
/usr/bin/java -jar /home/ec2-user/test-1.0-SNAPSHOT.jar --spring.profiles.active=dev --Xmx=1300M -XX:+HeapDumpOnOutOfMemoryError -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M
Issue is when the application fails with "java.lang.OutOfMemoryError: Java heap space" errors in the logs and does not export heap dump and gc logs in the location specified. Has someone used jar with systemd and faced similar issues.
Maybe if you set WorkingDirectory=/home/ec2-user/ to the directory where you want your logs/dumps to appear. Because without that I'm not sure where systemd is trying to create the gc.log you specified.
Or alternativly you could try to specifiy the whole path to the gc.log: -Xloggc:/home/ec2-user/gc.log
Well i have found out that the problem was with the new line and \ characters, If we place all the jvm arguments in the single line it works!!!.
ex:
ExecStart=/usr/bin/java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/location/heapdump.bin -Xloggc:/location/gc.log -jar test.jar --Xms=512M --Xmx=1300M --spring.profiles.active=${env}
Note: Some of the arguments are deprecated in Java 11, so check document arguments to include as per use case.
https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-3B1CE181-CD30-4178-9602-230B800D4FAE

Issue with copy JRE into docker and run java command

I am copying the working version of the JRE directory into docker and trying to run /JRE/bin/java.
But it throws ash: java not found error. I am doing the same in a linux VM . Just copying the JRE folder and executing java command which works fine in VM. I don't want to download JRE from anywhere.
Want this specific JRE bundled.How to resolve this.
I entered into the shell console and navigated to the JRE/bin/ directory and executed "java". even then it fails . The error is same ash: java not found error.
Dockerfile:
FROM alpine:latest
ENV HOME=/root \
DEBIAN_FRONTEND=noninteractive \
LANG=en_US.UTF-8 \
LANGUAGE=en_US.UTF-8 \
LC_ALL=C.UTF-8 \
DISPLAY=:0.0 \
DISPLAY_WIDTH=1024 \
DISPLAY_HEIGHT=768
RUN apk --update --upgrade add \
bash \
fluxbox \
x11vnc \
xterm \
xvfb
COPY MyJavaApp MyJavaApp/
WORKDIR /MyJavaApp
ENV PATH="./JRE/bin:${PATH}"
When are you copying the JRE directory to the docker? i.e Docker build time or after spinning up the Docker container?
Looks like you are correctly copying the local Java directory to the image, however the current location cannot access the java binaries, thus, make sure to set the PATH. It should be something like,
RUN export PATH=/JRE/bin:${PATH}
or pass the path to the ENV in the Dockerfile,
ENV PATH="/JRE/bin:${PATH}"

Could not find or load main class -Dcom.sun.management.jmxremote.port=8090

I am trying to run jconsole to see the beans working but in the jconsole they aren't visible so I tried with jmx but getting the following error?
Could not find or load main class -Dcom.sun.management.jmxremote.port=8090
This is the command that I run ob my Linux Terminal
java -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port=9010 \ -Dcom.sun.management.jmxremote.local.only=false \ -Dcom.sun.management.jmxremote.authenticate=false \ -Dcom.sun.management.jmxremote.ssl=false

Problem changing Java version using alternatives

I'm not quite sure how I got into this mess, but for some reason I'm not able to change the current version of Java using alternatives. I can run alternatives --config java and type my selection but when I echo the version number for either java or javac, it spits back out 1.5 every time (despite alternatives showing the current version is 1.6). The server I'm working with is running RHEL5, by the way.
I have verified that the paths used in alternatives are pointing to the correct directories. Here's some output from my session:
[brilewis#myserver]$ sudo
/usr/sbin/update-alternatives --config
java
There are 3 programs which provide
'java'.
Selection Command
** 1 /usr/lib/jvm/jre-1.4.2-gcj/bin/java
+ 2 /usr/java/jdk1.5.0_10/bin/java
3 /usr/java/jdk1.6.0_16/bin/java
Enter to keep the current
selection[+], or type selection number: 3
[brilewis#myserver]$ java -version
java version "1.5.0_10" Java(TM) 2 Runtime
Environment, Standard Edition (build
1.5.0_10-b03) Java HotSpot(TM) Server VM (build 1.5.0_10-b03, mixed mode)
[brilewis#myserver]$ sudo /usr/sbin/update-alternatives --config java
There are 3 programs which provide 'java'.
Selection Command
** 1 /usr/lib/jvm/jre-1.4.2-gcj/bin/java
2 /usr/java/jdk1.5.0_10/bin/java
+ 3 /usr/java/jdk1.6.0_16/bin/java
Enter to keep the current selection[+], or type selection number:
UPDATE: The following is the output of echo $PATH:
/usr/java/jdk1.5.0_10/bin:/usr/local/apache-ant-1.7.1/bin:/usr/local/apache-tomcat-6.0.24:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/NX/bin:/home/brilewis/bin
UPDATE (4/26/10): I followed Bert's suggestion and removed JAVA_HOME from the PATH environment var in /etc/profile. After doing this, I was able to use alternatives to change the version of Java. The only problem is that when I try to run javac, I get "-bash: javac: command not found". This does not happen when the version is set to 1.5.
For Oracle Java 6u30, once you've installed their RPMs you can configure alternatives:
/usr/sbin/alternatives --install "/usr/bin/java" "java" "/usr/java/default/bin/java" 2 \
--slave /usr/bin/javac javac /usr/java/default/bin/javac \
--slave /usr/bin/javadoc javadoc /usr/java/default/bin/javadoc \
--slave /usr/bin/jar jar /usr/java/default/bin/jar \
--slave /usr/bin/keytool keytool /usr/java/default/bin/keytool \
--slave /usr/bin/orbd orbd /usr/java/default/bin/orbd \
--slave /usr/bin/pack200 pack200 /usr/java/default/bin/pack200 \
--slave /usr/bin/rmid rmid /usr/java/default/bin/rmid \
--slave /usr/bin/rmiregistry rmiregistry /usr/java/default/bin/rmiregistry \
--slave /usr/bin/servertool servertool /usr/java/default/bin/servertool \
--slave /usr/bin/tnameserv tnameserv /usr/java/default/bin/tnameserv \
--slave /usr/bin/unpack200 unpack200 /usr/java/default/bin/unpack200 \
--slave /usr/share/man/man1/java.1.gz java.1.gz /usr/java/default/man/man1/java.1.gz \
--slave /usr/share/man/man1/keytool.1.gz keytool.1.gz /usr/java/default/man/man1/keytool.1.gz \
--slave /usr/share/man/man1/orbd.1.gz orbd.1.gz /usr/java/default/man/man1/orbd.1.gz \
--slave /usr/share/man/man1/pack200.1.gz pack200.1.gz /usr/java/default/man/man1/pack200.1.gz \
--slave /usr/share/man/man1/rmid.1.gz rmid.1.gz /usr/java/default/man/man1/rmid.1.gz \
--slave /usr/share/man/man1/rmiregistry.1.gz rmiregistry.1.gz /usr/java/default/man/man1/rmiregistry.1.gz \
--slave /usr/share/man/man1/servertool.1.gz servertool.1.gz /usr/java/default/man/man1/servertool.1.gz \
--slave /usr/share/man/man1/tnameserv.1.gz tnameserv.1.gz /usr/java/default/man/man1/tnameserv.1.gz \
--slave /usr/share/man/man1/unpack200.1.gz unpack200.1.gz /usr/java/default/man/man1/unpack200.1.gz
Then activate the configuration:
/usr/sbin/alternatives --config java
And select /usr/java/default/bin/java from the menu.
Plus you must gzip the man pages
gzip /usr/java/default/man/man1/*.1
Also, the Oracle java RPMs might have clobbered your alternatives symlink so force it to be normal.
ln -sf /etc/alternatives/java /usr/bin/java
I can change the default Java on CentOS using these steps:
Add the IBM JDK:
alternatives --install /usr/bin/java java /opt/WebSphere/AppServer/java/bin/java 3
Set the new IBM JDK as default:
alternatives --config java (then select #3 in the list)
Type java -version at the prompt to see the result.
The only way I was able to solve the problem was to start over again by removing /var/lib/alternatives/java and installing each JDK again. I did the same for javac and jar. After doing this, I was able to switch between versions without any issues.
alternatives works by changing a symlink in the /usr/bin directory. However, if your path contains a valid executable earlier in the path, that will be used instead.
In this case, judging from your previous comments, it sounds like /usr/java/jdk1.5.0_10/bin is somewhere in the path and should be removed.
For a BASH shell, the path is usually set in ~/.bashrc or (less likely?) ~/.bash_profile
Updated with more explanations
Check which java executable is really running, e.g.
$ type java
If this shows something other than /usr/bin/java, then you've likely got a specific JRE/JDK hardcoded in your path. This is fine, but you won't be able to use change Java versions using RH alternatives for any account that hardcodes a specific JRE/JDK in its PATH in this way. However, other packages/accounts (e.g. system processes) that don't hardcode a specific JDK version into its path will use the alternatives-specified JRE.
Check your JAVA_HOME environment variable, e.g.
$ echo $JAVA_HOME
If this is set, this will sometimes point the java executable at a different JRE/JDK, regardless of where the java executable itself lives. Again, its not unusual to set this, but you won't be able to use change Java versions using RH alternatives for any account that hardcodes a different JAVA_HOME.
All that said, for development in my account, I normally set a specific JDK in my path and set JAVA_HOME to point to a specific JDK, rather than rely on the system settings. RH alternatives is fine to control what Java version other packages use, but for my own development, I like to explicitly target the Java I want to use.
When using the alternatives method, if you want to use an alternative, it must first be installed. I believe RPMs would include this as a part of the install, but in the case where manual installs are performed, you can still manually install. For example, with java,
alternatives --install "/usr/bin/java" "java" "/usr/java/example/bin/java" \
--slave /usr/bin/javac javac /usr/java/example/bin/javac \
...
What this does is to install an alternative for the java symlink. For each slave, it also builds/updates the symlink to some other value specified in another alternative, when you switch it. So if you were to switch to a different version of java using alternatives, and the alternative specifies a slave for javac, javac will repoint to the new version as well.
My full list is as follows:
alternatives --install /usr/bin/java java /usr/java/<version>/bin/java 1500 \
--slave /usr/bin/ControlPanel ControlPanel /usr/java/<version>/jre/bin/ControlPanel \
--slave /usr/bin/jar jar /usr/java/<version>/bin/jar \
--slave /usr/bin/javac javac /usr/java/<version>/bin/javac \
--slave /usr/bin/javaws javaws /usr/java/<version>/bin/javaws \
--slave /usr/bin/jcontrol jcontrol /usr/java/<version>/bin/jcontrol \
--slave /usr/bin/keytool keytool /usr/java/<version>/bin/keytool \
--slave /usr/bin/orbd orbd /usr/java/<version>/bin/orbd \
--slave /usr/bin/pack200 pack200 /usr/java/<version>/bin/pack200 \
--slave /usr/bin/policytool policytool /usr/java/<version>/bin/policytool \
--slave /usr/bin/rmid rmid /usr/java/<version>/bin/rmid \
--slave /usr/bin/rmiregistry rmiregistry /usr/java/<version>/bin/rmiregistry \
--slave /usr/bin/servertool servertool /usr/java/<version>/bin/servertool \
--slave /usr/bin/tnameserv tnameserv /usr/java/<version>/bin/tnameserv \
--slave /usr/bin/unpack200 unpack200 /usr/java/<version>/bin/unpack200 \
--slave /usr/share/man/man1/java.1 java.1 /usr/java/<version>/man/man1/java.1 \
--slave /usr/share/man/man1/javac.1 javac.1 /usr/java/<version>/man/man1/javac.1 \
--slave /usr/share/man/man1/javaws.1 javaws.1 /usr/java/<version>/man/man1/javaws.1 \
--slave /usr/share/man/man1/keytool.1 keytool.1 /usr/java/<version>/man/man1/keytool.1 \
--slave /usr/share/man/man1/orbd.1 orbd.1 /usr/java/<version>/man/man1/orbd.1 \
--slave /usr/share/man/man1/pack200.1 pack200.1 /usr/java/<version>/man/man1/pack200.1 \
--slave /usr/share/man/man1/policytool.1 policytool.1 /usr/java/<version>/man/man1/policytool.1 \
--slave /usr/share/man/man1/rmid.1 rmid.1 /usr/java/<version>/man/man1/rmid.1 \
--slave /usr/share/man/man1/rmiregistry.1 rmiregistry.1 /usr/java/<version>/man/man1/rmiregistry.1 \
--slave /usr/share/man/man1/servertool.1 servertool.1 /usr/java/<version>/man/man1/servertool.1 \
--slave /usr/share/man/man1/tnameserv.1 tnameserv.1 /usr/java/<version>/man/man1/tnameserv.1 \
--slave /usr/share/man/man1/unpack200.1 unpack200.1 /usr/java/<version>/man/man1/unpack200.1
Hope this helps.

Categories