In this example we launch an H2 server, but it doesnt matter; same for any Java process.
Create a password file at ~/.jmxremote.password using $JRE_HOME/lib/management/jmxremote.password as a template.
JMX_PORT=1616
java \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.host=localhost \
-Dcom.sun.management.jmxremote.port=$JMX_PORT \
-Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT \
-Dcom.sun.management.jmxremote.local.only=true \
-Djava.rmi.server.hostname=localhost \
-Dcom.sun.management.jmxremote.authenticate=true \
-Dcom.sun.management.jmxremote.password.file=$HOME/.jmxremote.password \
-cp ~/opt/h2-1.4.197.jar org.h2.tools.Server -baseDir ~/var/h2/ -tcpBecause, this is an insecure configuration (no SSL), the client is should setup an local (-L) SSH tunnel an connect on the server (and then connect to localhost:$JMX_PORT).
Note that JMX binds to localhost for the connection port $JMX_PORT (due to com.sun.management.jmxremote.host=localhost), but it also opens other random ports that are bound to 0.0.0.0: i think that those are protected from remote access due to com.sun.management.jmxremote.local.only=true.
See also: https://stackoverflow.com/questions/35367232/how-to-configure-jmx-to-bind-to-localhost-only
Setup the SSH tunnel to the server. Let 1616 be the $JMX_PORT:
ssh -Llocalhost:1616:localhost:1616 server.localdomain
Use jconsole or jvisualvm to connect to remote process localhost:1616 via JMX.