JIT compiler - compiler choosing options - java

On 64 bit linux, with java8, when running java command, it seems all the 3 options -client / -server / -d64 are using the 64-bit server compiler.
The questions are: (for 64bit linux with java8)
Since -client and -server use the same compiler, does it makes any difference to specify one of the 2 options?
For a long running java daemon program, is it preferred to use -server together with -XX:+TieredCompilation or without it, when during the startup time it's ok to be a little slow.

Look at the file jre/lib/amd64/jvm.cfg. You'll likely see the lines
-server KNOWN
-client IGNORE
This means that -client option is ignored. -server also does nothing, since JDK 8 for x64 has only one JVM that includes both C1 and C2 compilers, and the tiered compilation is on by default.
with -XX:+TieredCompilation or without it
Does not matter, because this option is on by default. The advanced compilation policy works fine for both client-grade and server-grade applications. There is no usually need to turn it off manually.

Related

Java option MaxDirectMemorySize reported differently by java vs. jinfo

I restarted a Java process with new memory options -Xms4G -Xmx4G -XX:MaxDirectMemorySize=6G and wanted to verify if these changes got correctly applied, especially the 6G of direct memory.
The first solution I found for verifying this was via java itself, but this simply reported a 0, implying that my new settings had no effect:
bash-4.4$ java -XX:+PrintFlagsFinal -version | grep MaxDirect
uintx MaxDirectMemorySize = 0 {product}
openjdk version "1.8.0_242"
OpenJDK Runtime Environment (build 1.8.0_242-b08)
OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)
A second solution I found later was via jinfo, which apparently confirm the 6G that I indended to set:
bash-4.4$ jinfo -flag MaxDirectMemorySize 1
-XX:MaxDirectMemorySize=6442450944
I've relied on the java -XX:+PrintFlagsFinal for other purposes before, but now I wonder why it doesn't return the expected values. Why are java and jinfo returning different results?
There's (at least) two different JVMs.
[Expanding comment:] java {nothing} -XX:+PrintFlagsFinal -version creates a new JVM, changes none of its configuration from the default, and prints the resulting configuration, which is the default configuration with no changes -- and the default for MaxDirectMemSize is indeed zero.
OTOH jinfo {option} pid attaches to an existing already running JVM and obtains or changes the configuration of that JVM (although the specific pid 1 isn't usually a JVM but it often is in a docker container as you are using). jps lists the running JVMs you can attach to, with options to include JVM arguments and/or application arguments.
Does this imply that the same verification cannot be achieved with java? Unlike jinfo it cannot be attached to a running JVM?
Yes and no; it gets a bit Wonderlandy.
java by itself creates a new JVM, separate from any existing one. Normally this JVM runs a user-specified program, but with -version as you used it just prints version info and exits without running anything.
Now, the attach API is accessible from (and actually written partly in) Java. What jinfo does in more detail is:
create a new JVM; this doesn't use the java executable, so it isn't easily visible, but it actually is a JVM just like one from java
use that JVM to run some predefined Java code, which used to be in JDK/lib/tools.jar; I haven't bothered to track down where it is (and exactly how to access it) in the new post-8 modulated Java
that Java code when run in the jinfo JVM attaches to, and accesses information in, the specified other JVM, which was previously created and configured with java -Xvarious to run your application
You can actually do steps 2 and 3 yourself; you could write Java code that uses the API to attach to a specified (or otherwise located) existing JVM and get the info you want, and use java to run in JVM#2 your code that accesses info in existing JVM#1. But why bother, when jinfo (and jstat jmap jconsole etc) already does what is needed?
For that matter, jps also does this -- it runs its own JVM to run Java 'tool' code that uses the attach API to list JVMs. That's why the list produced by jps, unless filtered, includes jps itself. In fact, if you could run jps during the very short time jinfo is running, the jps list would include jinfo also -- and if you could determine the pid for jps and run jinfo on that pid during the very short time jps is running, you could get jinfo-type information on the jps JVM.
Clear enough?

Java HotSpot(TM) 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 [duplicate]

I'm starting a new Spring 5 project with Java 14. It compiled, but gave me a warning:
OpenJDK 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release
Any ideas how to solve it?
It's just a warning because JVM's verifies are much faster then before. If you are really not willing to see that, you could just remove -Xverify:none and -noverify from your JVM options.
In IDEA you can do that like this:
In "edit configuration", select your application, and uncheck "Enable launch optimization" in the right panel. Then start your application, the warning will be disappeared but launch optimization is disabled.
For anyone else who comes here looking for how to silence this warning in Leiningen (Clojure), export LEIN_JVM_OPTS="-XX:TieredStopAtLevel=1" was recommended by Leinigen's maintainer and worked for me.
Setting this option means that only the C1 compiler is used. To learn more about the C1 and C2 compilers, see Working with the JIT Compiler and What exactly does -XX:-TieredCompilation do?
In the Eclipse world this can also be controlled in two places:
either disable the Fast startup option in the Run/Debug configuration
or remove the corresponding deprecated argument (-noverify) from the Spring Boot Fast Startup Java argument list:

How to find if the JVM installed on the machine is HotSpot or JRockit on Windows OS

How to find if the JVM installed on a Windows box is HotSpot or JRockit, or from any other vendor for that matter?
Run this command in your terminal
java -XshowSettings:properties -version
You may use command java -version from command prompt, which prints JVM information
For humans have a look at the various system properties defined. You most likely want java.vendor.
http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
For programs it is best to use reflection to test for the JVM specific facility you need instead of relying on arbitrary property values.
If you want to know whether the currently running JVM is HotSpot or JRockit, check System.getProperty("java.vm.name"). For me, it gives Java HotSpot(TM) 64-Bit Server VM on HotSpot and Oracle JRockit(R) on JRockit, although different versions/platforms may give slightly different results, so the most reliable method may be:
String jvmName = System.getProperty("java.vm.name");
boolean isHotSpot = jvmName.toUpperCase().indexOf("HOTSPOT") != -1;
boolean isJRockit = jvmName.toUpperCase().indexOf("JROCKIT") != -1;
Thorbjørn's suggestion to use java.vendor has the problem that the same vendor may produce multiple JVMs; indeed, since Oracle's acquisitions of BEA and Sun, both HotSpot and JRockit now report the same value: Oracle Corporation
If you want to find all JVMs installed on a system: the problem with Nambari's answer, to use the command java -version, is that the JVM can be installed on a machine yet not be present in the path. For Windows, scanning the registry could be a better approach.

Build times increase substantially when switching to Java 7

We use Java within our build process, as it is used to resolve/publish our dependencies via Ivy.
No problem, nor have we had with it for 2 years, until we've tried to upgrade Java 6 Update 26 to Version 7 Update 7, whereas a build on a local developer PC (WinXP) now takes 2 hours to complete, instead of 10 minutes!!
Nothing else has changed on the PC, making it the absolute target for our concerns.
Does anyone know of any reason as to why version 7 of Java would make such a speed difference like this?
UPDATE: The build process is NAnt-based, so Java.exe is called from a NAnt script, running in a Command (DOS) window.
I'm using JDK 7u7 and I noticed a better performance by tuning some VM Options.
You could try the G1GC and AgressiveOpts to help with compile time.
Follow the settings I use in my editor:
-Xss8m
-Xmn256m
-Xms512m
-Xmx1024m
-XX:PermSize=256m
-XX:MaxPermSize=512m
-XX:+UseG1GC
-XX:+OptimizeStringConcat
-XX:+UseStringCache
-XX:+AggressiveOpts
You will find each option's description in the VM Options link.
I hope it helps.
In my experience, Java 7 was a huge step backward in terms of speed and compatibility. I've found it slower not only to compile, but running the JRE as well.
I've also had major issues running eclipse with it (and yes, i've used update 7).
And from my standpoint there's nothing in Java 7 that i need. I like the ForkJoinPool, and can get that as an add on library for Java 6.
Maybe Java 8 will be better.
First, did you remove JDK6 or leave it in place? Check your JDK_HOME and any other place it is specified to ensure that you are actually using JDK7. In the XP console type java -version and ensure it is what is expected. (Close/reopen the command prompt to pick up changes in the Win GUI.)
It was never stated what version of XP you are running -- 64-bit or 32-bit. Ensure the appropriate JDK environment is on the machine. (Depending on exactly what is executing, this can make a tangible difference. Also, the best bet for debugging is to keep it the same as before -- reduce variables.)
Troubleshoot the issue and narrow it down. Does an Eclipse installation perform slower after the upgrade? (Eclipse itself runs in a JVM. It's a good baseline.) Is Eclipse pointing at the correct JDK when you test it? Try other Java tools to see if there is a performance difference. Breakpoints and logging at different control points in the build and any Java executables are your friends.
Since Nant is .NET based, have you looked at the Java process that is actually launched? Is your Ivy distribution really old?
All this said, it is hard for me to believe this is a Java issue and not a configuration challenge on the Windows box. Have you tried it on any other machines, anyway?

Will a 64 bit JVM run in 64 bit mode when no option like -d32 or -d64 is specified

I have installed a 64 bit Java on a 64 bit Centos machine. My query is that if I dont specify the -d64 option will the JVM run in 32 bit mode even if there is no 32 bit JVM installed ?
Also I was a bit curious if we can use the -d64 option with "javac". If yes, then what does it imply or where could it be used? I came across this when reading this article.
Thanks
The selection of the data model (bits) for the JRE is to constrain the operation of the application to only run in one mode. The java byte code is designed to work in both data models, so for the 100% pure java applications, will work according the behavior and benefits of each architecture.
But, if your application use native libs that work only in one mode, then the application will fail under the not supported one. For that, you must explicitly indicate in which mode it should run.
When you set -d32 or -d64 the JRE will not start your application if it can't run in the selected mode.
From the Oracle document you linked to:
How do I select between 32 and 64-bit operation? What's the default?
The options -d32 and -d64 have been added to the Java launcher to specify whether the program is to be run in a 32 or 64-bit environment. On Solaris these correspond to the ILP32 and LP64 data models, respectively. Since Solaris has both a 32 and 64-bit J2SE implementation contained within the same installation of Java, you can specify either version. If neither -d32 nor -d64 is specified, the default is to run in a 32-bit environment.
Other Java commands (javac, javadoc, etc.) will rarely need to be executed in a 64-bit environment. However, the -d32/-d64 options may be passed to these commands and then on to the Java launcher using the established -J prefix option (eg: -J-d64).
All other platforms (Windows and Linux) contain separate 32 and 64-bit installation packages. If both packages are installed on a system, you select one or the other by adding the appropriate "bin" directory to your path. For consistency, the Java implementations on Linux accept the -d64 option.
(emphasis mine)
So, according to the document you linked to, the default is to run in a 32-bit JRE, and it is possible to run javac in a 64-bit JRE by passing -J-d64 rather than simply -d64.
However, note that this document also says that it applies to Java 1.4, and says nothing about more recent versions of Java.

Categories

Resources