Why a virtual machine is needed execute a java program.? [duplicate] - java

This question already has answers here:
Why the Java language need bytecode? Why java design in this way? [closed]
(5 answers)
Closed 6 years ago.
Why a Java code run through JVM (java code ->byte code -> machine code ). Why can't it compile to native machine code directly like "C".

To make Java code platform independent.
Updated
If a C-programme is compiled on a particular platform, then it would produce compiled code that is capable of running only on the platform on which it was compiled. A C-program compiled on windows machine cannot be run on Linux/Unix/MacOS machines.
One of the main design goals of Java was to make the code platform-independent.
This was achieved by adding an extra step in between code compilation and code execution. That is the step of generating the 'byte code'.
Compiling a Java programme results into what is called as "byte code" file, having an extension of .class. The byte code actually contains instructions that can be interpreted by Java Virtual Machine. That is to say that 'javac' converts Java programme into a set of instructions that a JVM can understand.
JVM - Java Virtual Machine, runs on top of the OS and is implemented for each platform (OS and underlying hardware) separately.
With this design it is possible to compile a Java program in Windows machine and run the generated .class file on a Linux box, thus achieving platform independence.

Because any machine that has an implementation of the JVM can run any program that's been compiled into Java Byte Code (in theory). Java byte code also acts as a higher-level language that different languages can compile into. Of course, different languages can be compiled into the same machine-code, but that ties compiled code to one type of machine, instead of non-machine-specific byte code.
The JVM implementation also takes care of the machine specific details instead of the app programmer. This allows Java code to do away with the 32/64 bit code variations that are typically resolved using preprocessors in c/c++.

Because that way Java can be implemented for the JVM which has a defined architecture and instruction set. Different machines can have their own JVM on which Java programs can be executed without having to worry about machine on which JVM is running. In addition many optimizations are also added in JVM.

Related

How java solved portability?

Java compiler converts Java code to bytecode and then JVM converts bytecode to machine instructions. As far as I have understood, JVM are built for different platforms (processor + OS). Then how can we say that Java is platform independent? Ultimately, we require a JVM which is platform dependent?
As you have mentioned yourself, JVM is platform-dependent. That's it - JVM is platform-dependent, but not JAVA. After all, the JVM needs to be run in someway inside the native machine, so it must have to be specific to that platform.
JAVA is portable in the sense that the compiled code is portable. For example, if you compare with C, both the C and Java source codes are portable, that means both of them provide source code portability. Once you have a source code written in a Windows PC, you can transfer that exact code in another Linux machine and both Java and C code will compile and run fine in both machines.
But, what about object code portability?
We know, when we compile a C code, it produces the machine readable object code. So, if you compile a C source code from one machine, then that object code may not be run from another machine if they are not compatible. But, in case of JAVA, if you compile a Java source code to bytecode from one machine, that bytecode can be run in any machine that runs the JVM.
Another interesting fact, by successful compilation of a Java source code, we are also producing a byte code for some unknown future CPU which doesn't even exist as JVM acts as a kind of virtual CPU.
The end-user writes code in java and that is platform independent.
The JVM engineer works on creating the JVM and the JRE and within it the compiler and the interpreter for different platforms. Therefore that absolves the end-user to worry about porting their codebase to different platforms. Write once and then run it on all platforms (as long as there is a JVM available for that platform).
So from the perspective of the end-user (Java programmer) the java code is indeed platform independent since it can run anywhere without any changes. Even though the JVM is ported to different platforms and is indeed platform dependent.
Difference with C/C++:
As it is with the JVM, there exists a C/C++ compiler for each platform responsible for translating source to machine/processor instructions. These machine instructions are understood by the processor, for instance: intel etc. Therefore a C/C++ compiler is made available for each platform it supports. However, you might need to link to specific OS/platform specific libraries in your program. That will make your program platform specific and will need to be rewritten for another platform by linking to that platform's version of that library. That becomes C/C++ programmer responsibility. Also each C/C++ compiler has its own vagaries specific to a platform unlike a JVM which provides a consistent view across platforms detailed below.
In case of Java, you are removed from tapping into platform specificities (unless the JVM or Java libraries do not provide it but they usually cover most of the basics). The java code taps into JVM and Java libraries and the JVM is responsible for translating that to bytecode or to machine instructions (to improve performance) at runtime. Unless you use JNI in your java source, you do not have to worry about portability. For instance: within your Java program, you can access the native environment, the host memory, some OS characteristics etc., and your code is still portable. The JVM provides the infrastructure in that the native calls to extract that information specific to the platform. However there might be some platform specific functionality that your java program requires that is not provided by the JVM or Java libraries and therefore you need to JNI and your portability suffers as a result.
Note: C/C++/Java all have source code portability. But what the JVM provides is binary portability. The compiled or interpreted java code runs on an abstraction called the JVM (Virtual Machine). The java programmer writes to that interface instead of the platforms that the JVM runs on. There is a clear separation here.

Why do we use the Java virtual machine? [duplicate]

This question already has answers here:
Why a virtual machine is needed execute a java program.? [duplicate]
(3 answers)
Closed 2 years ago.
I am trying to wrap my head around the Java Virtual Machine and why it uses bytecode. I know it has been asked so many times, but somehow I couldn't finally make the correct assumption, so I researched many things and decided to explain how I think it works and if it's correct.
I understand that in C++, compiler compiles the source code on the specific (architecture + operating system). So, compiled version of C++ for (x86 + Windows) won't run on any other architecture or operating system.
My assumptions
When Java compiler compiles the source code into bytecode, It doesn't do the compilation depending on architecture or operating system. The source code will always be compiled to the same bytecode if it's compiled on Windows or Mac. Let's say we compiled and now, send the bytecode to another computer (x86 + windows). In order for that computer to run this bytecode, It needs JVM. Now, JVM knows what architecture + operating system it's running on. (x86 + windows). So, JVM will compile bytecode to x86 + Windows and it will produce machine code which can be run by the actual computer now.
So, even though we use Java Virtual Machine, we still run the actual machine code on our operating system and not on the virtual machine. Virtual Machine just helps us to transform bytecode into machine code.
This means that when using Java, the only thing we have to worry about is installing JVM and that's it.
I just always thought that the Virtual Machine is just a computer itself where it would run the code in its own isolated place, but in case of JVM, i don't think that's correct, because I think machine code JVM produces still has to be run on the actual operating system we have.
Do you think my assumptions are correct?
When Java compiler compiles the source code into bytecode, It doesn't do the compilation depending on architecture or operating system. The source code will always be compiled to the same bytecode if it's compiled on Windows or Mac.
All correct.
Let's say we compiled and now, send the bytecode to another computer (x86 + windows). In order for that computer to run this bytecode, It needs JVM. Now, JVM knows what architecture + operating system it's running on. (x86 + windows). So, JVM will compile bytecode to x86 + windows and it will produce machine code which can be run by the actual computer now.
This is mostly correct, but there are a couple things that are a bit "off"
First of all, to execute the bytecodes on any computer you need a JVM. That includes the computer on which you compiled the bytecodes.
(It is theoretically possible that a computer could be designed and implemented to execute the JVM bytecode instruction set as its native instruction set. But I don't know if anyone has ever seriously contemplated doing this. It would be pointless. Performance would not be comparable with hardware that you can by for a couple of hundred dollars. The JVM bytecode instruction set is designed to be compact and simple, and it is relatively easy to JIT compile. Not to be executed efficiently.)
Secondly a typical JVM actually operates in two modes:
It starts out executing the bytecodes in software using an interpreter.
After a bit, it selectively compiles bytecodes of heavily used methods to the platform's native instruction set and executes the native code. The compilation is done using a JIT compiler.
Note that the JIT compiler is platform specific.
So, even though, we use Java Virtual Machine, we still run the actual machine code on our operating system and not on the virtual machine.
That is correct.
[The Java] Virtual Machine just helps us to transform bytecode into machine code.
The JVM actually does a lot more. Things like:
Garbage collection
Bytecode loading and verification
Implementing reflection
Providing native code methods for bridging between Java classes and operating system functionality
Implementing infrastructure for monitoring, profiling, debugging and so on.
This means that when using Java, the only thing we have to worry about is installing JVM and that's it.
Yes. But in a modern JDK there are other alternatives; e.g. jlink will generate an executable that has a cut-down JRE embedded in it so that you don't need to install a JRE. And GraalVM supports ahead of time (AOT) compilation.
I just always thought that the Virtual Machine is just a computer itself where it would run the code in its own isolated place, but in case of JVM, i don't think that's correct, because I think machine code JVM produces still has to be run on the actual operating system we have.
Ah yes.
The term "virtual machine" has multiple meanings:
A Java Virtual Machine "executes" Java bytecode ... in the sense above.
A Linux or Windows virtual machine is where the user's application and the guest operating system are running under the control of a "hypervisor" operating system. The applications and guest OS use the native hardware to execute instructions, but they don't have full control of the hardware.
And there are potentially other shades of meaning.
If you conflate JVMs with other kinds of virtual machine, you can get yourself in knots. Don't. They are different enough that conflating the concepts in not going to help you understand.
When compiling java code, java-bytecode is created.
This bytecode is platform independent and can be run by the JVM. This means that other programming languages like Kotlin can also generate this java-bytecode and target the JVM.
So you are correct about the java-bytecode being the same for every platform.
Where you aren't entirely correct however is, that the JVM converts the java-bytecode to native bytecode.
The JVM executes the java-bytecode instead and gives the instructions to the operating system. While executing, the JVM compiles bunches of java-bytecode to native code, which the operating system can then execute. This happens while the code is executed so a class that is never loaded will also never be executed and will never end up as machine code.
Due to this we can use features like Reflection where some of the java-bytecode of a class files can be modified at runtime before being compiled to native machine code.
The JVM basically sits between the operating system and the java-bytecode. In some sense just like a normal VM.
The article below has a nice visualization of the JVM.
https://www.guru99.com/java-virtual-machine-jvm.html
The java byte code is a form of intermediate code.
That code can be interpreted, a JVM is such an interpreter emulating (simulating) every single byte code instruction. This is slow but easily portable.
That code can be compiled to native code, normally a JVM contains a just-in-time compiler for code that is indeed executed. This native code can be optimized for the current machine it is running on, and the native code does not need to be loaded from file, and code inlining can be done.
So the JVM principly is a turbo-charged interpreter, of java byte code, portable to many platforms.
Context:
[Other languages] Microsoft's C# language is more of a compiler.
[Other intermediate codes] LLVM IR is an intermediate code from the C side, compilable.
[Other JVMs] There are more than one JVM, with different techniques.

Compilation process in Java [duplicate]

This question already has answers here:
How exactly does java compilation take place?
(9 answers)
Closed 7 years ago.
A compilation process takes source code to be translated into machine language.
So far, I have mentioned .java files (source code) and .exe files (0s and 1s).
So, What is the purpose of .class files that seem to be in the middle of the entire process?
We already have executable files coming from java source code and they don't depend on these .class files.
I know .class files are also created after compilation, but their content (which I don't know) differ from .exe files because they can only run with a java compiler and not as an independent application like an executable file will do.
Thank you!
Java was created to be platform independent. .class files contain JVM (Java Virtual Machine) code instead of normal machine code as found in .exes. The JVM is idealized, with features no real processor actually has, but it is less complex than the language of Java itself and is an abstraction layer above the platform specific hardware.
When a Java program is run, the JVM interprets the Java bytecode so that it can actually run on the CPU. The initial javac compilation relieves the JVM from having to compile the entire program on execution and hampering performance, while the abstraction lets the code run anywhere as long as a JVM is installed.
This is in contrast to .exe files, which contain platform specific machine code directly. Windows itself provides abstraction that keeps things from breaking, but because the code is still platform specific it won't work on non-Windows systems and there are separate versions for 32- and 64-bit systems (unless, of course, emulators).
The bytecode interpretation the JVM does is still very expensive compared to .exe files loading machine code directly. Therefore, if some part of the code is called enough, the JIT (Just-In-Time compiler) will kick in and compile the JVM code directly to platform specific machine code and store that in memory to increase performance in these active areas. If that area of code is used enough, the JIT does optimization on that code too, and because it can run profiling on running code it can optimize things with assumptions .exe compilers can't make. This is why many large Java programs have a warmup time before they start working more efficiently.

How does Java bytecode deal with multiple platforms?

For example, let's say you have a java program that simply opens a window. This will obviously result in different assembly code for different operating systems (on windows it will eventually have to call CreateWindowEx). So how does the Java bytecode (or any other similar language) represent something platform specific like this?
The JVM is OS-dependent, byte code isn't.
This means that bytecode is a sort of "generic" language that JVM will interpret end execute according to the system it's running on.
UPDATE
As Chris Jester-Young says, my answer is not strictly correct:
The bytecode for a 100% pure Java program is indeed platform-independent. The underlying Java platform classes that such programs invoke are, of course, not.
Most of the time, the JVM will also JIT compile, not just interpret. (You can enable pure-interpretation mode, but it'll be slow!)
Serenity said this:
Typically, the compiled code is the exact set of instructions the CPU requires to "execute" the program. In Java, the compiled code is an exact set of instructions for a "virtual CPU" which is required to work the same on every physical machine.
So, in a sense, the designers of the Java language decided that the language and the compiled code was going to be platform independent, but since the code eventually has to run on a physical platform, they opted to put all the platform dependent code in the JVM.
This requirement for a JVM is in contrast to your Turbo C example. With Turbo C, the compiler will produce platform dependent code, and there is no need for a JVM work-alike because the compiled Turbo C program can be executed by the CPU directly.
With Java, the CPU executes the JVM, which is platform dependent. This running JVM then executes the Java bytecode which is platform independent, provided that you have a JVM availble for it to execute upon. You might say that writing Java code, you don't program for the code to be executed on the physical machine, you write the code to be executed on the Java Virtual Machine.
The only way that all this Java bytecode works on all Java virtual machines is that a rather strict standard has been written for how Java virtual machines work. This means that no matter what physical platform you are using, the part where the Java bytecode interfaces with the JVM is guaranteed to work only one way. Since all the JVMs work exactly the same, the same code works exactly the same everywhere without recompiling. If you can't pass the tests to make sure it's the same, you're not allowed to call your virtual machine a "Java virtual machine".
Of course, there are ways that you can break the portability of a Java program. You could write a program that looks for files only found on one operating system (cmd.exe for example). You could use JNI, which effectively allows you to put compiled C or C++ code into a class. You could use conventions that only work for a certain operating system (like assuming ":" separates directories). But you are guaranteed to never have to recompile your program for a different machine unless you're doing something really special (like JNI).
Source: How is Java platform-independent when it needs a JVM to run?
In the Java programming language, all source code is first written in plain text files ending with the .java extension. Those source files are then compiled into .class files by the javac compiler. A .class file does not contain code that is native to your processor; it instead contains bytecodes — the machine language of the Java Virtual Machine1 (Java VM). The java launcher tool then runs your application with an instance of the Java Virtual Machine.
please read this doc by oracle
.class files(i.e byte code) are same but not the JVM ,It differs with OS.
There are different Java Virtual Machine binaries for each operating system. They can run the same Java bytecode (classes, jars), but the implementations is sometimes different.
For example, all the window handling code is implemented differently on Windows, Unix and Mac. Each of them will call the OS native calls to open a window or to draw something. You don't have to care about it, because the Virtual Machine automatically does it.

Why is java both compiled and interpreted [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is Java a Compiled or an interpreted programming language?
Why is Java both compiled and interpreted language?
We first compiles the java program using javac(compiling) and the run the program using java(interpreting). What is the advantage of that?
Also, where does JIT role come into the picture?
Compile once and run anywhere is one of the reasons.
JVM is OS specific. So, JVM interprets compiled .class (byte code) file and converts into machine specific instruction set.
The Java compiler typically compiles source code into an intermediate language, expressed generically as "byte code". That itself is not machine code for your native hardware, but in a sense it is "machine" code for the Java virtual machine.
The benefit of this separation is that (in theory) you can implement a VM on many different platforms, but all of them will be able to run the same compiled Java byte code.
A just-in-time compiler is part of a hypothetical VM, and actually translates bits of byte code dynamically into real, native machine code, as and when needed. This grew out of the observation that running a Java program purely in a VM was a lot slower than equivalent native code. JIT compilation has made the Java VM competitive in terms of performance when compared to natively compiled code.
Java is "compiled" into byte code
The byte code is "interpreted" as the program executes
A JIT compiler and "precompile" byte code into native machine code, optimizing execution time
Here is an article giving more details about Java JIT:
http://en.wikipedia.org/wiki/Just-in-time_compilation

Categories