tags:

views:

408

answers:

5

The JIT compiler has been around for some time. Occasionally it comes to my mind that, "hey, why not just compile Java source file directly to machine code?"

Along with compiled library, we can get rid of the cumbersome JVM.

The only barrier I can think of is the garbage collector. How's your thoughts?

PS: Oh, you say portability? WTH is that? Plus, I'm forced to install a JVM in the first place.

+19  A: 

Well, my friend uses Ubuntu, and I use Windows XP, and my other friend uses OSX.

When I send them a jar that I compiled they can both run the file without any changes.

That is why you should not get rid of the JVM.

jjnguy
This is basically it. The JVM's job is so we don't have to write platform specific code. That compilation you speak of is where that platform coupling takes shape.
Josiah Kiehl
I love not needing to specify the OS for my eclipse plugins
Chris Thompson
You still end up writing code which targets specific implementations of the JVM though. Not all Java code runs the same across all JVM implementations which basically means you code is back to being platform dependant. Instead of the platform being specific hardware now it is a particular implementation of the JVM.
Simon
@Simon I generate a lot of Java code for all kinds of things and I can't say that I run into implementation specific issues. It's not like .Net where they seem to go out of their way to break everything with each new release.
Brian Knoblauch
@Simon As a C++ developer, I can say that the novelty of the JVM would still be welcomed despite the obvious shortcoming you say. It's usually easier to tell me customer which software version must be installed than to tell him which computer architecture and OS he must use.
San Jacinto
@Brian I'm not saying it is a very common experience, just pointing out that the term platform independent is somewhat vague. Java has just moved the platform from the hardware to the software. It is quite likely that different implementations have subtly different designs which have unintended consequences or just different bugs which make your program perform differently depending on the implementation.
Simon
@Simon if you write Java code that depends on a particular JVM implementation or underlying OS, then that's your own fault... most Java code runs on any JVM implementation unmodified.
Jesper
If you use filenames like "C:\\Windows\\myfile.txt" you automatically have a platform dependency. Those you must avoid. That helps immensely.
Thorbjørn Ravn Andersen
@Jesper If you read what I said a little more carefully it is not quite so easy as that. As I said previously it is quite possible that the differences are simply the result of a bug or are an unintended consequence of a small design difference. It is not about taking advantage of something which overtly requires a particular JVM implementation. The fact of the matter is that there are differences between them and those differences are what make the JVM the platform now rather than the hardware.
Simon
+4  A: 

On some platforms (mostly embedded ones), it's just as you say (or else the machines speak java natively). You can also download compilers that do what you are suggesting, but I imagine you lose a lot of the Java API in the process.

Back to your question, the main reason why is that the people who design the languge and specification want to have it. Plain and simple. It offers portability in the consideration that the "hard" part of making portable code supposedly only has to be done once per environment (another poster spoke of 3 different OS's running the JVM) rather than once per each environment per project. Have you ever tried to make even mostly-portable C++ code without the aid of frameworks like Qt or packages like Boost? It gets VERY difficult, and even then you must still re-compile for each architecture.

San Jacinto
+2  A: 

Beside portability another issue that comes to mind is dynamic classloading which is difficult to handle via machine code. How would servlet containers work in such a scenario? Maybe it works well for embedded Java, but I don't think for J2EE.

Would the .class form just be an intermediate binary that is converted to machine code before execution? Or would you directly compile from Java source to machine code?

Timo Westkämper
Actually, this is done all the time in the form of shared libraries. Slightly more complex, but nothing special there.
San Jacinto
But not in portable form.
Timo Westkämper
You (as the designer) could make them portable since you are the one to write the compiler for each system. This is no different than what happens under other languages that compile to machine code, and once you compile the application to machine code, you're throwing out the idea of binary-portability to begin with. I just don't see the point of what you're stating :)
San Jacinto
+1  A: 

Bytecode generation is necessary for platform independence of code.

JVM (JVM is different for all platforms) reads these bytecode and converts these into machine code depending upon which platform its running. This makes Java compiled code platform independent. JVM also does optimizations which makes Java fast.

YoK
+7  A: 

vm can do complex optimizations based on information only available at runtime. Static compile time optimization simply can't compete. Java is fast because it is running on the vm.

watch this

http://www.infoq.com/presentations/Towards-a-Universal-VM

irreputable
could you provide an example?
San Jacinto
@San Jacinto When statically compiling code you do not have the kind of information about so called "hot spots" in your code. Code which is called repeatedly and probably with the same characteristics. When doing live optimisation the Java virtual machine can optimise specific sections of code based on current usage patters. Hence the phenomenon often seen with Java programs when they start quite slowly and then improve as time goes on as the hot spot compiler provides specific optimisations for the running code.
Simon
@San Jacinto: an example of such an optimisation would be counting the number of times a specific branch is taken, and then creating native code that takes advantage of this to create a "fast path" for this branch. Static compilers can't do this (though they might "guess" at the most common branch).
mikera
Sorry, guys. I'm used to having similar things happen in hardware, not SW :). Thanks for the education.
San Jacinto
Thanks, interesting presentation.
Jesper
A good example is a getX() call, which - not being final - is not a candidate for inlining ahead-of-time, but which HotSpot can detect is not overridden and can be treated as final, and hence inlined. If loading new classes breaks assumptions, that code goes back to interpreted, and the JIT-mechanism starts over.
Thorbjørn Ravn Andersen