Change Default Java VM to Client - java

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.

Related

How to use different java version by alias?

I have some tools that can only be run by java 8. So i downloaded java 8, but now i have two versions of java installed at the same time (os : Ubuntu):
java-1.11.0-openjdk-amd64 1101 /usr/lib/jvm/java-1.11.0-openjdk-amd64
java-1.8.0-openjdk-amd64 1081 /usr/lib/jvm/java-1.8.0-openjdk-amd64
My question is: is it possible to call these both versions by different aliases? For example i type:
"java" to call java 11 (the default) and
"java8" to call java 8
You could do it in a couple of ways. The easiest way would be to put the following 2 lines in your profile initialization file:
alias java='/usr/lib/jvm/java-1.11.0-openjdk-amd64/bin/java'
alias java8='/usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/java'
Other ways are depending on whether you are the admin of the machine or not. You can create soft links like this:
/usr/bin/java -> /usr/lib/jvm/java-1.11.0-openjdk-amd64
(Not recommended since certain tools in your system may depend on /usr/bin/java).
Update: Try to use sdkman if you can. Makes the job of installing java versions and setting up JAVA_HOME env variable simple.
You can do this as well for JAVA_HOME:
alias java8="export JAVA_HOME=`/usr/libexec/java_home -v 1.8`"
alias java11="export JAVA_HOME=`/usr/libexec/java_home -v 11`"
Updated:
To run java directly use:
$ alias java8="`/usr/libexec/java_home -v 1.8`/bin/java"
$ alias java11="`/usr/libexec/java_home -v 11`/bin/java"
$ java8 -version
java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)
$ java11 -version
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)
You can hardcode your path as well.
I have some tools that can only be run by java 8. So I downloaded java 8, but now I have two versions of java installed at the same time (os : Ubuntu).
You could do this using aliases (see other answers) but this has the problem that only a shell will respect an alias ... and then only if it has the alias defined or loaded by the shell:
Aliases are not inherited via the environment.
Whether a tool's launch script will see the aliases will typically depend on whether you put the alias definitions into the correct shell init file.
It is also possible that an application's launch script will assume that java8 or java11 is a genuine (absolute or relative) pathname, and try to resolve it via the file system.
In short, there is a good chance that using an alias won't work in your use-case.
So a better idea is to arrange that the appropriate Java is on the Command Search Path. You could do this a number of different ways:
You could use the Ubuntu "alternatives" system to globally switch between Java 8 and Java 11.
You could update the PATH variable so that (for example) the Java 11 executables come before the Java 8 executables. This could be done in shell init files (per user or globally), in the application launch scripts ... or by hand.
You could even replace "/usr/bin/java" or whatever with a direct symlink to the version you want to use. (This is crude, and I wouldn't recommend it.) Note that the Java command entries in "/usr/bin" are probably already symlinks.)

Executing a jar file with -Xms and -Xmx arguments from a Python program

When I try to execute a Java jar file from within my Python program, as below:
pathToMyJar = ...
argumentsToMyJar = ...
myJavaCommandLine = 'java -Xms4g -Xmx16g -jar ' + pathToMyJar + ' ' + argumentsToMyJar
print(myJavaCommandLine)
os.system(myJavaCommandLine)
I'm getting the following error:
Invalid maximum heap size: -Xmx16g
The specified size exceeds the maximum representable size.
But when I run the same from PowerShell (essentially, copy-and-paste of the command-line printed by the Python program), the following runs just fine.
PS D:\Temp> java -Xms4g -Xmx16g -jar <pathToMyJar> <argumentsToMyJar>
What am I missing?
I've tried the following in vain:
replacing the os.system() call with subprocess.call() with the same result
reducing the -Xmx16g to lower values (I've 256G of RAM on a 64-bit machine)
ensuring that the same Java version is run on the command-line and from the Python program.
Here's the Java version:
PS D:\Temp> java -version
java version "1.7.0_71"
Java(TM) SE Runtime Environment (build 1.7.0_71-b14)
Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode)
The message:
The specified size exceeds the maximum representable size.
points at a heap size that is too big for the instruction set architecture that is being used to run the Java executable; i.e. you are using a 32-bit JVM.
I suspect that your methodology for "ensuring that the same Java version is run on the command-line and from the Python program" is incorrect. You need to ensure that you are running a 64-bit JVM in both cases. It is not just the version number that matters.
(The fact that java from the command prompt allows a large heap implies that you have both 32-bit and 64-bit JRE or JDK installs on your machine.)
Another possibility is that your python application is running with a ulimit on per-process memory usage ... but I've expected a different error message for that.
The only plausible explanation is you have installed a 32-bit version of Java on a 64-bit machine. Obviously, a 32-bit version of Java can address a maximum of 232 bytes (or 4 GB). Uninstall the 32-bit version, and install the 64-bit version then (assuming you're on Windows) reboot.

How do I produce a heap dump with only a JRE?

We have a JRE installed on our production environment, but not a JDK. The versions of the JRE and OS are below.
[me#mymachine ~]$ java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
[me#mymachine ~]$ uname -a
Linux mymachine.mydomain.com 3.10.35-43.137.amzn1.x86_64 #1 SMP Wed Apr 2 09:36:59 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
It doesn’t appear as if the jmap tool is present anywhere on the system, and without root access, I’m not in a position to install it in any system location. What can I do to get a heap dump (i.e. produce a .hprof file)?
Also, we're using JBoss 7.1.3.AS if that matters.
Use jattach, a tool created by JVM hacker Andrei Pangin. It's tiny (24KB), works with just JRE and supports Linux containers.
jattach PID-OF-JAVA dumpheap <path to heap dump file>
Built-in tools like jmap, jconsole, and jvisualvm are only available in a JDK. Another option is to add the VM argument -XX:+HeapDumpOnOutOfMemoryError which tells the JVM to automatically generate a heap dump when an OutOfMemoryError occurs, and the argument -XX:HeapDumpPath to specify the path for the heap dump.
If you cannot upgrade your JRE to use tools like the ones in the server JRE 7 (http://www.oracle.com/technetwork/java/javase/downloads/server-jre7-downloads-1931105.html), you may have to consider third-party profiling tools like JProfiler or ones list here.
The only way seems to be to zip your local SDK6 and put it somewhere on the server. Then open a remote console and from within the bin directory of that SDK dump the JRE.
If your client forbids uploading executable files, you are out of luck of course.
kill -3 <pid>
thread dump will be sent in to <TOMCAT_HOME>/logs/catalina.out file
OR use combination below :
-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=~/jvm.log
if you want to redirect., but for that you have to run your process through command line.

How do i know which default settings are enabled for Sun JVM?

i want to try CompressedOops on my JVM. No I wonder if it might be enabled by default. I run this jvm on debian/squeeze:
$ java -version
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03, mixed mode)
Some people say it is enabled by default, some say it is not:
from: http://forums.yourkit.com/viewtopic.php?f=3&t=3185
Yes, you are right, I also checked it
and Compressed Oops is not activated
by default in Java6u21 64-bit, I do
not understand why it said so in the
links I provided.
I tried to check it with jconsole/JMX but had no luck to find an attribute named CompressedOops or alike.
Does anybody know where i get a list of all jvm options for a specific build with their default values?
regards
Janning
You can run with -XX:+PrintFlagsFinal to print the values of all flags at startup of the JVM.
Alternatively, you can use the jinfo tool to check the value of a flag in a running JVM:
> jinfo -flag UseCompressedOops 7364
-XX:+UseCompressedOops
Use jps to find the pid of the process.

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

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]

Categories