Differences between JVM implementations - java

Where do JVM Implementations differ (except licensing)?
Does every JVM implement Type Erasure for the Generic handling?
Where are the differences between:
JRockit
IBM JVM
SUN JVM
Open JDK
Blackdown
Kaffe
.....
Deals one of them with Tail-Call-Optimization?

JVM implementations can differ in the way they implement JIT compiling, optimizations, garbage collection, platforms supported, version of Java supported, etc. They all must meet set of features and behaviors so that it will execute your Java bytecodes correctly.
As you've pointed out, the major difference tends to be in licensing. Other non-technical differences tend to be in free/paid support options, integration with other technologies (usually J2EE servers), and access to source code.
Note: While a J2EE server runs on the JVM, some servers have integrated tools for monitoring, analyzing, and tweaking JVM performance.
As far as technical differences, those have grown less significant over the years. Once upon a time, the IBM and JRockit JVM's had far superior performance to the reference Sun implementation. This was due to significant differences in the types of runtime optimizations, differences in garbage collection, and differences in native-code (and how much native code various classes uses). These performance differences aren't as significant anymore.
Some JVM's also include or integrate with diagnostics and monitoring tools. JRockit includes a set of tools for monitoring your JVM performance. Sun provides various JMX-based tools with overlapping features to do the same. IBM Websphere once upon a time included a similar set of tools for their whole J2EE application server (not sure if they still do, but I would assume that's still true)...
Some of the open source JVM's tend to have a little slower performance because they have been redeveloped from the ground up. As such, they've got a bit more catching up to do. Last I checked about 2 years ago, Blackdown was significantly slower (1.5x-2x?) than the Sun JVM. It was also a bit behind of supported versions of Java.

Type erasure is a compiler function and as such JVM independent.

Things like type erasure are done by the compiler to be backward compatible with older JVMs. Most JVMs should support all the features you need, but some may be more optimized than others. I'm guessing the Sun JVM is probably the fastest.

JIT compiling is one thing that some JVM:s don't have.

If the JVM claims to be Java it must pass the TCK, providing a lot of stock funcitonaltiy.
The differences are in non-core places, like garbage collection, the jconsole/visualvm in the Sun JVM, precompilation etc.
clarification: TCK is the test suite that a virtual machine has to pass in order to be officially Java compliant.

Another difference between JVMs is behaviour on undocumented API. (e.g. com.sun.xxx)
For example, Sun's JVM and IBM's JVM both have slightly different behaviour on signal handling. (IBM's JVM doesn't allow the application to trap the "INT" signal in certain cases.)

JVM is like a virtual Machine that works to Load the class and Bytcode varifier, execute the code. while Applocaion Programming Interface is Collection of Packages. and Packages are collection of class. Java program execute where JVM Installed and Works.

Tail-call optimization is not yet supported by Java. John Rose is leading efforts to include this in a future release, and has described the approach, and some of the issues involved.

Related

Does JVM translates the byte code to machine instructions? [duplicate]

I always come across articles which claim that Java is interpreted. I know that Oracle's HotSpot JRE provides just-in-time compilation, however is this the case for a majority of desktop users? For example, if I download Java via: http://www.java.com/en/download, will this include a JIT Compiler?
Yes, absolutely. Articles claiming Java is interpreted are typically written by people who either don't understand how Java works or don't understand what interpreted means.
Having said that, HotSpot will interpret code sometimes - and that's a good thing. There are definitely portions of any application (around startup, usually) which are only executed once. If you can interpret that faster than you can JIT compile it, why bother with the overhead? On the other hand, my experience of "Java is interpreted" articles is that this isn't what they mean :)
EDIT: To take T. J. Crowder's point in: yes, the JVM downloaded from java.com will be HotSpot. There are two different JITs for HotSpot, however - server and desktop. To sum up the differences in a single sentence, the desktop JIT is designed to start apps quickly, whereas the server JIT is more focused on high performance over time: server apps typically run for a very long time, so time spent optimising them really heavily pays off in the long run.
There is nothing in the JVM specification that mandates any particular execution strategy. Some JVMs only interpret, they don't even have a compiler. Some JVMs only JIT compile, they don't even have an interpreter. Some JVMs have both an intepreter and a compiler (or even multiple compilers) and statically choose between the two on startup. Some have both and dynamically switch back and forth during runtime. Some aren't even virtual machines in the usual sense of the word at all, they just statically compile JVM bytecode into native machinecode ahead-of-time.
The particular JVM that you are asking about, Oracle's HotSpot JVM, has one interpreter and two compilers, called the C1 and C2 compiler, also colloquially known as the client and server compilers, after their corresponding commandline options. HotSpot dynamically switches back and forth between the interpreter and one of the compilers at runtime (but it will not switch between the two compilers, you have to specify one of them on the commandline and then only that one will be used for the entire runtime of the JVM).
As per document here Starting with some of the later Java SE 7 releases, a new feature called tiered compilation became available. This feature uses the C1 compiler mode at the start to provide better startup performance. Once the application is properly warmed up, the C2 compiler mode takes over to provide more-aggressive optimizations and, usually, better performance
The C1 compiler is an optimizing compiler which is pretty fast and doesn't use a lot of memory. The C2 compiler is much more aggressively optimizing, but is also slower and uses more memory.
You select between the two by specifying the -client and -server commandline options (-client is the default if you don't specify one), which also sets a couple of other JVM parameters like the default JIT threshold (in -client mode, methods will be compiled after they have been interpreted 1500 times, in -server mode after 10000 times, can be set with the -XX:CompileThreshold commandline argument).
Whether or not "the majority of desktop users" actually will run in compiled or interpreted mode depends largely on what code they are running. My guess is that the vast majority of desktop users run the HotSpot JVM from Oracle's JRE/JDK or one of its forks (e.g. SoyLatte on OSX, IcedTea or OpenJDK on Unix/BSD/Linux) and they don't fiddle with the commandline options, so they will probably get the C1 compiler with the default 1500 JIT threshold. (But applications such as IntelliJ, Eclipse or NetBeans have their own launcher scripts that usually supply different commandline arguments.)
In my case, for example, I often run small scripts which never actually reach the JIT threshold, so they are never compiled. (Nor should they be.)
Some of these links about the Hotspot JVM (what you are downloading in the java.com download link above) might help:
Java SE HotSpot at a Glance
The Java HotSpot Performance Engine Architecture
Frequently Asked Questions About the Java HotSpot VM
Neither of the (otherwise-excellent) answers so far seems to have actually answered your last question, so: Yes, the Java runtime you downloaded from www.java.com is Oracle's (Sun's) Hotspot JVM, and so yes, it will do JIT compilation. HotSpot isn't just for servers or anything like that, it runs on desktops and takes full advantage of its (very mature) optimizing JIT compiler.
Jvm spec never claim how to execute the java bytecode, however, you can specify a JIT compiler if you use the JVM from hotspot VM, JIT is just a technique to optimize byte code execution.

Which programming languages can only run on JVM?

Depending on where you live, trying to download the JVM may result in a message like this:
The Java(TM) cannot be downloaded to your machine. You are located in an embargoed country.
In my opinion, teachers in IT should inform children about problems that can emerge from this restricted access (OpenJVM is not Oracle JVM and is not used in enterprise/government). No official JVM updates means no fixing of vulnerabilities, exploits, bugs and so on. If JVM is officially unavailable it is reason enough to inform children about the possible consequences.
Hence my question: what languages can only run on JVM/OpenJVM?
Java bytecode can be recompiled to LLVM and the same probably applies for Scala - quite possibly for all of them. Clojure also has an implementation on the CLR. All other languages that can run on the JVM already have their own implementations (like Python and Ruby).
Technically, I don't think there are many languages that can only run on (Oracle's) JVM. The question, of course, is whether all the alternative implementations are of any help to you, considering that they may be forbidden as well.
Furthermore, I sense that this isn't the point of your question: you said that a given alternative may not be used over there because it isn't an "official" product. If people, corporations or the government actively and consciously choose a specific implementation over any alternatives, then by definition there is no answer for them.
You can't download the JVM officially from the www.java.com website OR other Oracle's websites as it has been embargoed for your nation. But, there are still other means (sources) like en.softonic.com and several others which won't bar you for downloading the JVM.
Next, once you have JVM installed in your machine, you can run and execute all the JVM supported languages like Java, Scala, Jython and so on in your machine. It has nothing to do with your location and position once you have JVM in your machine. I wish you successful alternate downloads and enjoy the languages like Java, etc.
Also, please refer to this link for list of more such languages:
http://en.wikipedia.org/wiki/List_of_JVM_languages

has JSR-335 special support in JVM? Boost for functional JVM-based languages?

JSR-335 is said to come soon along with Java 8. It brings i.e. support for closures and virtual extension methods.
I wonder if there is any particular support for this on the JVM level?
If so, can we hope for speed improvements in JVM-based functional languages that provide closures and extension-methods-like features (such as traits or implicits in scala)?
Edit:
reading this oracle presentation on Java 8 by Brian Goetz, it would appear that:
- closures don't require
- virtual extension methods do require
particular JVM-support.
Could this mean that in scala, some of the implicits, and traits could be reimplemented in a more efficiently way?
I don't think extension methods can be used to implement traits -- a method implementation can't call super on them (afaik -- I might be wrong), and the override semantics would be different. Furthermore, it would not cover fields, just methods.
There isn't anything JVM can do to help with implicits, because there's no inherent problem with them. They are normal instances passed as normal parameters. Looking them up makes the compiler slow, but JVM can't help with that either.
I don't see any of these features helping with anything in Scala, but that's almost moot, actually. Scala still generates JVM 1.5 bytecode with JVM 1.5 classfiles. You can turn on JVM 1.6 bytecode, which makes little difference. With Scala 2.10, 1.6 classfiles will be enabled on an experimental basis.
The reason for that is pretty simple: Java 1.7 runs 1.5 classfiles with 1.5 bytecode, but not the other way around. There's still a lot of people running older versions of Java, and that is unlikely to change.
So I don't see any Java 1.8 features in the radar, unless they bring a huge advantage. And, even then, they'll most likely be available for code compiled with Scala, but not on the Scala library itself. Likewise, unless it brings a huge advantage, I don't see libraries being made available in both versions.
I think the speed of Scala is very close to Java already. It is the dynamic typed jvm languages are slow (such as Groovy). And actually JDK 7 came out with the new feature invokedynamic for the purpose of improve those dynamic jvm language:
http://java.sun.com/developer/technicalArticles/DynTypeLang/

Will the JVM be extended to handle generics?

What do you think? Will the JVM ever get support for generics?
Quite likely that would not only require substantial changes to the JVM, but also to the class file format,
but languages running on the VM would greatly benefit from it.
Edit: The Java language actually supports some sort of generics as a compile time feature, which adds some casts to the bytecode, which people had to add manually before.
The decision to not introduce changes to the JVM or the class file specification was well understood at these times, because they didn't want to break backward-compatibility and Java was the only significant language for the JVM these days.
While this decision might have been appropriate for the Java language, it has significantly reduced the amount of freedom other languages have to choose how they want to implement generics on the VM.
Considering that Sun/Oracle have proclaimed to make the JVM a friendlier place for alternative languages, will they actually do what they promised or consider they that the low cost addition of "InvokeDynamic" is enough?
In my opinion it is unlikely.
It would simply be too disruptive to apply these changes to the Java language. Linguistic and runtime backwards compatibility with two different models of generics would be a nightmare for the designers.
And without, Java to drive changes to the JVM, it is hard to see how Oracle would / could justify doing the work required.
The only possibilities I see are:
Oracle decides to develop a successor language to Java (that is not backwards compatible) that does generics, closures and a whole bunch of things better. That would be a really brave business decision, and I don't think Oracle is capable of making it.
A bunch of other people / companies get together and fork the JVM specification and the codebase. That's also a brave move to make.
I don't think it is likely that Oracle would resource a major change to the JVM just to support languages that they had no commercial interest in. We are talking about here Oracle ... where the business types have a much tighter control over what the engineering types get to do than in the dying Sun days. (Hey ... we could start a whole Jack Vance theme going here :-)

Killer facility or scenario that would make another JVM a better choice than the Sun JVM?

For Java SE there are several JVM's available for running in production on x86:
IBM J9
Oracle JRockit - http://www.oracle.com/technology/products/jrockit/index.html
Apache Harmony - http://harmony.apache.org/
The one in OS X (if a Mac) which appears to be Sun with Aqua Swing.
OpenJDK
plus some custom offerings for running on a server:
Azul - http://www.azulsystems.com/
Google App Engine Java - http://code.google.com/intl/da/appengine/docs/java/overview.html
Other platforms:
Sun Solaris JVM - better scalability than x86?
(edit) GNU compiler for Java - http://gcc.gnu.org/java/ - can compile to native code on multiple platforms.
The Sun JVM has a distinct advantage with the jvisualvm program, which allows runtime inspection of running code. Is there any technical advantages of any other JVM that might make it a better choice for development and/or production?
In other words, is there a killer facility or scenario that would make any investment of time/effort/money worth it in another JVM?
(Please also suggest additional JVM's if they would be a good choice).
JRockit comes with JRockit Mission Control, which is a tools suite you can use to monitor the JVM and your application. You can download it here, it's free to use for development.
Mission Control has a lot of features that VisualVM is missing, for instance an online memory leak detector, a latency analyzer, Eclipse integration, JMX.logging to file. etc. If you want to compare VisualVM with Mission Control here are the release notes and the documentation for the latest version.
IBM J9
This is the kind of sales speech you can read or hear about J9:
IBM has released an SDK for Java 6. Product binaries are available for Linux on x86 and 64-bit AMD, and AIX for PPC for 32- and 64-bits. In addition to supporting the Java SE 6 Platform specification, the new SDK also focuses on, Data sharing between Java Virtual Machines, Enhanced diagnostics information, Operating system stack backtraces, Updated jdmpview tool, platform stability, and performance.
Some would say that the IBM SDK has some advantages beyond speed, that the use and expansion of PermGenSpace is much better than in the Sun SDK or GCJ (not a big deal for client applications, but heavy lifting J2EE servers, especially portal servers, can really cause the Sun JDK heartburn). But, according to this paper comparing Sun vs IBM JVM GC, it turns out that memory performance depends mostly on the application and not so much on the VM.
So, while it's true that the IBM JVM is well known for its troubleshooting features (more advanced than Sun's JVM), I'm not convinced by the differences at the GC level.
And Sun's JVM has a big advantage over IBM, at least on Solaris: DTrace providers. Actually, I've been mainly working with Weblogic on Solaris so Sun' JVM has always been the natural choice.
Oracle JRockit
I did some benchmarks of BEA/Oracle JRockit some years ago and it was indeed a fast VM and it was then supporting bigger heaps than Sun's VM at this time. But it has some stability problems which is not really good for production. Things might have changed since then though.
Apache Harmony
I might be wrong but, to me, Harmony is made of code donations from IBM (benefits: the community is doing maintenance) and I don't really see why I should consider Harmony rather than IBM J9.
Apple's JDK
I never had to use Mac for production so I can't really answer. I just remember Apple needed some time to bundle Java 6, and I don't know why. This is maybe not rational but this makes me suspicious.
OpenJDK
I know that some vendor are offering production support (e.g. RedHat with RHEL 5.3+, see this blog entry) for OpenJDK so it might be an option for platforms not supported by Sun. However, unless someone can tell me what makes OpenJDK work better than Sun's, I think I'll install Sun JVM on supported platforms.
So to me, the choices are actually: Sun's JVM unless I've to run some Websphere stuff, in which case I'd choose IBM J9. But to be honest, I've never faced a situation that I couldn't solve on a Sun's JVM and that could have justified (temporary) swapping to IBM' one so I can't actually tell if the troubleshooting features are that nice. But I admit that I may suffer from a lack of knowledge of IBM's JVM.
Some applications, like financial and computational science would benefit greatly from hardware implementations of decimal floating point. IBM has rolled out a series of processors (POWER6, the z9 and z10 mainframes) which implement the IEEE 754-2008 decimal floating point standard. The latest IBM JDK can use hardware acceleration for BigDecimals.
To allow developers to easily take advantage of the dedicated DFP hardware, IBM
Developer Kit for Java 6 has built-in support for 64-bit DFP through the
BigDecimal class library. The JVM seamlessly uses the DFP hardware when
available to remove the need for computationally expensive software-based decimal
arithmetic, thus improving application performance.
It's a very fringe case, but if you have a z10 mainframe handy and want to use its decimal floating point unit in Java, then the IBM JVM would be a better choice than the Sun JVM.
-- Flaviu Cipcigan
The typical feature/scenario that you should look at is performance and speed.
No matter what the white papers say, ultimately you need to benchmark and decide for yourself.
I am biased towards IBM, because I worked there a few years ago. I didn't personally deal with jvm development, but I remember that the emphasis of the jvm development group was on the following points:
Proprietary garbage collection optimizations. This includes not only faster GC, but also more configuration options, like GC for server and client. This was before Sun offered similar options.
Much faster (x10) native performance with the JNI interface. This was particularly important at the time when Eclipse/WSAD began to gain traction and swt was heavily used. If your app uses JNI a lot, then I think it's worth while for you to benchmark the IBM jdk against the Sun jdk.
Stability and reliability. I think this is only relevant if you buy commercial support from IBM, like SLA for a service tier (WebSphere and db2, clustered environment, etc.). In this case, IBM will guaranty the stability of their offering only if you use their jvm.
Regarding OpenJDK, I recommend that you look at this history of OpenJDK. My understanding is that OpenJDK 7 will be almost identical to Sun's jdk 7, so the performance is very likely to be identical. The primary differences will be licensing, and small components like webstart.
Oracle's jvm is useful if you want to run java code from within your database (via stored-procedure). It includes some optimizations that help the db run faster in this scenario.
As others have said, Sun has been catching up on their competitors. I think that in the 1.4 days the differences were much more noticeable, but no so much today. Regarding jvisualvm, other vendors also offer similar tools, so I don't think that is an issue.
Finally, there is one other metric (albeit a bit controversial) to indicate how serious are those vendors about their VM's. That is the number of related patents that they issue. It might be useful if you need to convince your boss, or if you like to read patents :)
Patent search: ibm and java - 4559 patents.
Patent search: oracle and java - 323.
Not strictly a JVM, but still a Java implementation: gcj. It has the advantage of supporting many processors, so if you target one of the embedded processors, gcj may be your only choice. Plus, since it is a true compiler (not just a JIT), you save the overhead of JIT compilation (both in memory and cycles) on the embedded target.
Back in the Java 1.4 days my team used the IBM JVM for a high-volume, message-based system running on Linux. Why did we do this? Because we benchmarked the different JVMs! JRockit was actually the fastest, but it would occasionally crash, so not so great for production.
As always with these things, measure it!
A few years back (JDK1.4), different JVMs had different advantages:
the IBM JVM was able to do heap dumps (programatically, on signals, or on OOM), and the heaproot utility was very useful to track memory leaks (less intrusive than profilers). No other JVM had this.
JRockit had many useful options that the Sun JVM didn't have, parallel collection. It was also (much) faster (and more stable than the Sun VM).
Today, the Sun one has these features, but I'm sure there are others.
Speed could be one. Garbage collection strategies another.
If you're using WebLogic, some bugs in the Sun JVM may lead to bugs in WebLogic. These bugs are more likely to be solved faster in JRockit.
From what I've been told, the main difference with Sun's JVM and IBM's JVM is in the actual garbage collectors, IBM's garbage collector(s?) are much more configurable than Sun's and are made only the business world in mind. Additionally IBM's JVM can tell a lot more than "I just crashed, here's my heapdump" in error situations which is obviously important in the business world which is the main living space of IBM's JVM.
So assuming I haven't been lied to, I'd say that IBM's JVM should be used when doing memory-intensive things in business software which relies on aggressive or otherwise highly tunable garbage collection.
In my own experience and at face value, I see simplicity in the IBM GC design. Sun's various and new GCs are excellent no doubt and offer a host of tuning options at minute levels, but even in some of the most active web apps I know that handle heavy/aggressive new objects and keep a lot in the heap for cache I rarely see GC ever exceed 1% even trying to keep the footprint low. Sure we could probably tune it better but there's a diminishing return.
I have had much more of a challenge in the exact same applications running IBM's JDK. In particular having issues with pinned clusters and having to tune -Xk.
Now I could mention about a dozen items that both IBM and Sun should implement for the killer JVM but not the scope of your question I presume :)
Incremental garbage collection and very small runtime size for realtime embedded systems is the only thing that would really matter enough to warrant chancing less stability or platform support. There was some jvm with this in mind but I forget its name now.

Categories