I have another solution using standard SSH tunneling and no firewall ports to open.
For me, SOCKS proxy does not work.
Start your JVM with options:
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=[port1]
-Djava.rmi.server.hostname=localhost
-Dcom.sun.management.jmxremote.rmi.port=[port2]
The important part is "rmi.server.hostname=localhost". Additionally, you explicitly define both ports (connect + "random" RMI port), "jmxremote.rmi.port" needs at least Java 7 update 4 (I read somewhere, did not check this info - use "lsof -i" or "netstat -at --numeric-ports" on your server machine to check the really used ports).
port1 and port2 can be the same and reduces ssh tunneling config.
(Of course, you may use authentication or SSL, depending on your security requirements.)
Connect via ssh to the server and forward your local port1 and port2 to localhost:port1|2 an the server. Important: port2 must be forwarded to the same port number on your local machine. (Reason: After connecting via port1 the JVM tells the JMX client the number port2 and the client connects to this port on the same host - i.e. localhost.)
In VisualVM open a JMX connection to localhost:port1 (without any proxy setting).