How to make sure I'm using the "server" JVM? - java

Sun's JVM comes in two flavors: -client and -server, where the Server VM is supposed to be optimized for long running processes, and is recommended for server applications.
When I run java with no parameters, it displays the usage options, which includes the following text:
The default VM is server,
because you are running on a server-class machine.
Having seen this, I didn't bother to add the -server to the process startup command.
However, on a recent JVM crash log, I noticed the following line near the end of the file:
vm_info: Java HotSpot(TM) Client VM (14.0-b16) for linux-x86 JRE (1.6.0_14-b08), built on May 21 2009 02:01:47 by "java_re" with gcc 3.2.1-7a (J2SE release)
It seems to me that Java is using the Client VM, despite what it says in the help message. I'm going to add the -server option to my startup command, but now I'm suspicious. So my question is: is there a way to make sure that the VM I'm running in is really the Server VM, without resorting to forcing a JVM crash?
The OS is ubuntu 8.04, but I'm using JDK 1.6.0_14 which I downloaded from Sun's website.

You can do
System.out.println(System.getProperty("java.vm.name"));
Which on my machine returns either:
Java HotSpot(TM) Client VM
or
Java HotSpot(TM) 64-Bit Server VM
Of course you shouldn't do anything critical based on this value, as it will probably change in the future, and will be completely different on another JVM.

I had a very similar question which I asked on ServerFault. I would say, if you care which version is run, always use -client or -server.

Well, if you explicitly start with the -server command line prompt, you are running in server mode. You can check that with this:
ManagementFactory.getRuntimeMXBean().getInputArguments();
You can look at RuntimeMXBean which may open up more information, but that would have to be tested on the specific JVM you are running.

Without writing any single line of code, if you use JConsole to connect to your JVM, under 'VM Summary' tab, it should say exactly which (server or client) Virtual Machine is being monitored.
For example,
Virtual Machine: OpenJDK Server VM version 1.6.0-b09
To remotely monitor your JVM using JConsole, simply enable the JMX (Java Management Extensions) agent by starting JVM with the following System Properties
> java.rmi.server.hostname=[your server IP/Name] // without this, on linux, jconsole will fail to connect to the remote server where JVM is running
> com.sun.management.jmxremote.authenticate=false
> com.sun.management.jmxremote.ssl=false
> com.sun.management.jmxremote.port=[portNum]

Related

JConsole not connecting to java process

When I start JConsole it identifies my java process(local) but it is not able to connect to it.
Connection Failed: Retry?
The connection to 17424 did not succeed.
Would you like to try again?
Selecting connect again gives the same error(17424 is the pid of the java process).On the other hand jvisualvm works perfectly. In jvisualvm I see the following details
PID: 17424
Host: localhost
Main class: Conatainer
JVM: Java HotSpot(TM) 64-Bit Server VM (23.6-b04, mixed mode)
Java: version 1.7.0_11, vendor Oracle Corporation
Java Home: /home/aniket/jdk1.7.0_11/jre
JVM Flags: <none>
Has anyone encountered this situation before? Is it a bug? Is there a work around?
You may be running JVisualVM as a different user than the user running the Java application. Make sure you're running as the same user or as a super user.
You could find the answer on the manual .
https://docs.oracle.com/javase/8/docs/technotes/guides/management/agent.html
Under previous releases of the Java SE platform, to allow the JMX client access to a local Java VM, you had to set the following system property when you started the Java VM or Java application.
com.sun.management.jmxremote

Change Default Java VM to Client

I installed Oracle's Java on Fedora 17, and I noticed that when using the command java -version it returns this
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)
Java seems to run the -server option by default. The help text came up as
-server to select the "server" VM
The default VM is server,
because you are running on a server-class machine.
Is there any way to change the default to client?
The default setting is defined in the file jvm.cfg. A content like
-client KNOWN
-server KNOWN
defines the client as the default.
-server KNOWN
-client KNOWN
sets the server as the default.
Source: www.rgagnon.com/javadetails/java-0566.html
jvm.cfg location
Unknown Mac OS X version:
/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home/jre/lib/jvm.cfg
Mac OS X version 10.9 without installing JDK:
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/jvm.cfg
Mac OS X version 10.9 with installed JDK version 1.8.0_u92:
/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/jvm.cfg
You can find your jvm.cfg from the command line (Terminal.app) using the command $ locate /jvm.cfg. You might need to update your locate database first, using the command: $ sudo /usr/libexec/locate.updatedb
From the docs:
Note: For J2SE 5.0, the definition of a server-class machine is one
with at least 2 CPUs and at least 2GB of physical memory.
So there doesn't seem any way to alter the server-class machine detection technique, I'm guessing you will have to stick to passing the -client VM argument if you need it on your machine.
Also worth noting is that this page is for Java 5, so things might be different with Java 6 and higher.
Starting with Java 5, you can specify this as an option to the JVM:
the -client option will make the VM start in client mode. In this mode, the start-up will be much faster.
the -server option will make the VM start in server mode. The start-up will be slower, but in the long run, it will execute faster.
See this question for more details about the differences about the 2 modes.
If you do not specify these options, the VM will check to see if you have at least 2 CPUs and at least 2 GB RAM. If you do, then it will start in server mode.
You can see the tables about how these decisions are made:
here for Java 5
here for Java 6 and
here for Java 7
FYI: they are all the same.

HtmlUnit is throwing Out Of Memory and maybe leaking memory

I use Selenium with HtmlUnitDriver with javascript enabled and I get Out Of Memory errors (I use Java). I just browse the same page. I am only using a single GET command. Which is the solution to overcome the situation?
I've had a similar issue. It ended up being an issue with auto-loading of frames... a feature that can't be disabled.
Take a look at this: Extremely simple code not working in HtmlUnit
It might be of help.
Update
Current version of HtmlUnit is 2.10. I started using HtmlUnit from version 2.8 and each new version ended up eating more memory. I got to a point in which fetching 5 pages with javascript enabled resulted in a process of 2GB.
There are many ways to improve this situation from a javascript point of view. However, when you can't modify the javascript (eg: if you are crawling a site) your hands are tied. Disabling javascript is, of course, the best way to go. However, this might result in fetched pages being different from the expected ones.
I did manage to overcome this situation, though. After many tests, I noticed that it might not be an issue with HtmlUnit (which I thought was the guilty one from the beginning). It seemed to be the JVM. Changing from Sun's JVM to OpenJDK did the trick and now the process instead of eating 2GB of memory only requires 200MB. I'm adding version information.
Sun's (Oracle) 32-bit JVM:
$java -version
java version "1.6.0.26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Server VM (build 20.1-b02, mixed mode)
OpenJDK 32-bit JVM:
$java -version
java version "1.6.0_18"
OpenJDK Runtime Environment (IcedTea6 1.8.13) (6b18-1.8.13-0+squeeze2)
OpenJDK Server VM (build 14.0-b16, mixed mode)
Operative system:
$ uname -a
Linux vostro1015 2.6.32-5-686-bigmem #1 SMP Sun May 6 04:39:05 UTC 2012 i686 GNU/Linux
Please, share your experience with this.
Give more memory to the JVM by adding this to the java command line that starts the JVM in which Selenium is running:
-Xmx512m
This example give a maximum of 512 Mb to the JVM.
It depends on where you're running Selenium from. If maven, you can add it to the MAVEN_OPTS environment variable, if Eclipse, you'll need to edit the run configuration for the test class, etc.
Related to HtmlUnit:
Do not forget to call webClient.closeAllWindows();. I always put it in a finally-block around the area I use the webclient. This way it is sure that all javascript is stopped and all resources are released.
Aslo useful is setting for the webClient:
webClient.setJavaScriptTimeout(JAVASCRIPT_TIMOUT);
webClient.setTimeout(WEB_TIMEOUT);
webClient.setCssEnabled(false); // for most pages you do not need css to be enabled
webClient.setThrowExceptionOnScriptError(false); // I never want Exceptions because of javascript
JAVASCRIPT_TIMOUT should be not too high long running javascript may be a reason for memory problems.
WEB_TIMEOUT think about how long you want to wait maximal.

CPU and profiling not supported for remote jvisualvm session

When monitoring a remote app (using jstatd) I can neither profile nor monitor CPU consumption. Heap monitoring (provided I do not use G1) works. jvisualvm provides the message "Not supported for this JVM." in the CPU graph window.
Is there anything missing in my setup? Google showed very few results.
The local environment (Mac OS X 10.6):
java version "1.6.0_15"
Java(TM) SE Runtime Environment (build 1.6.0_15-b03-219)
Java HotSpot(TM) 64-Bit Server VM (build 14.1-b02-90, mixed mode)
The remote environment (Linux version 2.6.16.27-0.9-smp (gcc version 4.1.0 (SUSE Linux))):
java version "1.6.0_16" Java(TM) SE
Runtime Environment (build
1.6.0_16-b01) Java HotSpot(TM) 64-Bit Server VM (build 14.2-b01, mixed mode)
Local monitoring works as advertised.
Remote profiling of code and allocation isn't supported by Visual VM. This sucks, however if you want to enable the CPU graph you can do this by enabling JMX with
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=12345
You may need to add some authentication settings too based on your network. The JMX settings will give you the CPU usage, and thread state, as well as doing a remote jstack.
A list of features for the remote version can be found here:
Visual VM features
EDIT
Get the latest version of visual vm 1.2.1 and download the VisaulVM-Sampler. This will read from a JMX connection to show the profiling information.
Connecting the eclipse java program.
Step 1: ensure your Eclipse -> Preferences -> Java -> Installed JREs is pointing to the same jdk where you have started the visualvm.
Step 2: Ensure Right click -> Run configuration has the following
-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=16001
Step 3: Importantly follow the below suggestion.
https://visualvm.java.net/troubleshooting.html#jpswin2
Description: An error dialog saying that local applications cannot be monitored is shown immediately after VisualVM startup. Locally running Java applications are displayed as (pid ###).
Resolution: This can happen on Windows systems if the username contains capitalized letters. In this case, username is UserName but the jvmstat directory created by JDK is %TMP%\hsperfdata_username. To workaround the problem, exit all Java applications, delete the %TMP%\hsperfdata_username directory and create new %TMP%\hsperfdata_UserName directory.
Also try JVMMonitor is decent plugin for eclipse stand alone program monitoring.
Is it because the remote version is (albeit slightly) greater than the local version?
I'm able to resolve this issue by providing same port number for JMX and RMI.
-Dcom.sun.management.jmxremote.port=29898
-Dcom.sun.management.jmxremote.rmi.port=29898
See Why Java opens 3 ports when JMX is configured?

how to tell if VM is running in server or client mode?

The Java hotspot vpm can be run with -client or -server argument. If neither is specified then it chooses one according to some rules.
Is it possible to tell whether a running VM is running in client or server mode when the mode is not specified on command line? I need this on a Windows box outside the running process.
I realize this is not a programming question, but I hope it is ok because it is programming related. Thanks in advance.
In Java, you could check this with this code:
String s = System.getProperty("java.vm.name");
// s = Java HotSpot(TM) Server VM
But this will be highly vendor specific.
From the command line, you could use jinfo (used to check a value of a given HotSpot VM option)
C:\>"c:\Program Files\Java\jdk1.6.0_16\bin\jps.exe" -l -m
21812 sun.tools.jps.Jps -l -m
19244 (eclipse)
C:\>"c:\Program Files\Java\jdk1.6.0_16\bin\jinfo.exe" -flag NewRatio 19244
-XX:NewRatio=12
Since:
it is rare to actually set the NewRatio Hotpot option and
the documentation specifies: Ratio of new/old generation sizes. [x86 -server: 8; x86 -client: 12]
12 means "Client".
Connect to the running Java process with jvisualvm. This will let you see the JVM arguments that have been used.
You can retrieve this information connecting to the MBean server. If you are running a Sun VM, you have an MBean with name "java.lang:type=Runtime" which exposes the attribute "VmName", whose value is the same as system property "java.vm.name". In example, for a server vm the value will be something like "Java HotSpot(TM) Server VM". VM's from other vendors may use a similar mechanism.
You can connect to the MBean server either using the tools included in the JDK, like jconsole or jvisualvm, or by writing your own tool using JMX if you need programmatic access.
If the jvm is started with -debug, you can connect to it using jdb, and use eval ...
eval System.getProperty("java.vm.name");
that or jinfo

Categories