Hi,
Very tough question? What really means Byte code? How it looks? What is JVM instruction? Whether JVM uses OS if it has own instruction set and Execution Unit? How it works?
The answer is here? You have already gone through my previous Posts, Otherwise go through below Posts.
JVM Basic
Java Method Area
Java Heap Area
Java Stack
Now find out the above answers below
32 and 64 bit JVM
When Javac compiles Java Source file, it create class file which contains Byte code, Byte code is nothing but included with JVM instruction Set.
Want to Read more about JVM instruction Set.
Wiki bytecode instruction
From Oracle
Java Ref
The designers of Java chose to use a combination of compilation and
interpretation. Programs written in Java are compiled into machine language,
but it is a machine language for a computer that doesn't really exist. This
so-called "virtual" computer is known as the
Java Virtual Machine,
or JVM.
The machine language for the Java Virtual Machine is called
Java bytecode. There is no reason why Java
bytecode couldn't be used as the machine language of a real computer, rather
than a virtual computer. But in fact the use of a virtual machine makes possible
one of the main selling points of Java: the fact that it can actually be
used on
any computer. All that the computer needs is an interpreter for
Java bytecode. Such an interpreter simulates the JVM in the
same way that Virtual PC simulates a PC computer. (The term JVM is also used
for the Java bytecode interpreter program that does the simulation, so we say that
a computer needs a JVM in order to run Java programs. Technically, it would
be more correct to say that the interpreter
implements the JVM than
to say that it
is a JVM.)
Of course, a different Java bytecode interpreter is needed for each type of
computer, but once a computer has a Java bytecode interpreter, it can run any
Java bytecode program. And the same Java bytecode program can be run on any
computer that has such an interpreter. This is one of the essential features of
Java: the same compiled program can be run on many different types of
computers.
The JVM/JRE uses Java bytecode as its instruction set and each JVM needs
to be compiled on and be runnable on the native/local hardware (and
therefore the local instruction set). This diagram from Wikipedia
illustrates this well I think:
he JRE/JVM needs to be compiled for the specific hardware it runs on,
though the Java bytecode definitions and interpretations by the JVM
itself stay the same. As you point out, the Java bytecode can be seen as
a kind of abstraction layer between the Java source code and the local
machine/binary code. It does allow for a separation of concerns between
the typical Java programmer and needing to know anything
machine-specific, as almost all of that is handled by the JVM/JRE.
An ISA (Instruction Set Architecture) specifies the entire set of
disciplines and techniques that apply to writing low-level software that
runs directly on the CPU. It includes a set of opcodes, which are
uncomposable direct CPU commands. The JVM recognizes its own set of
bytecodes (i.e. 8-bit opcodes) that direct the JVM to carry out
interpreter-primitive instructions. So, yes, the bytecode specification
makes up part of the JVM's ISA.
The JVM iterates through the list of opcodes executing them one by
one using its own memory
to emulate hardware components (e.g. stack, register, main memory) and
using primitive arithmetic and logic operations to emulate the ALU.
These emulated components also make up the JVM's ISA. This is the basic
construction of any interpreter, give or take. However, to improve the
runtime of Java applications, the JVM compiles "hotspots" to
machine-specific code for optimal performance. Hotspots are sections of
the code that are ran frequently. This is known as "Just-In-Time"
compilation, and can be done while the program is executing. This
technique brings Java's performance a lot closer to that of compiled
languages. JIT is used in the .NET framework as well.
Each operating system has its own JVM implementation, which may also
vary by the device's ISA. For example, you may have a JVM written for
Linux-Arm, Linux-x86, or Windows-x86. The JVM itself may be written in a
platform-independent (sort of anyway) language like C, but its JIT
compiler must support compilation to the device's instruction set.
The Java Virtual Machine (JVM) provides the entire environment for
running a Java program. It integrates with the Operating System, loads
classes, and runs programs. The Just-In-Time compiler (JIT) is just a
small piece that can be disabled (-Xint) but when enabled, provides a
useful improvement in performance. There have been implementations of
the JVM that didn't include a JIT, and implementations that worked by
pre-compiling Java to machine code just the same as traditional
languages, such as C or C++.
he key is the native language of the JVM: the Java bytecode. Any
language can be compiled into bytecode which the JVM understands - all
you need for this is a compiler emitting bytecode. From then on, there
is no difference from the JVM's point of view. So much so that you can
take a compiled Scala, Clojure, Jython etc. class file and decompile it
(using e.g.
JAD) into normal looking Java source code.
You can find more details about this in the following articles / threads:
I am not aware of any fundamental changes in the
Java 5 or
6 JVMs
which would have made it possible or easier for (code compiled from)
other languages to run on it. In my understanding the JVM 1.4 was more
or less as capable in that respect as JVM 6 (there may be differences
though; I am not a JVM expert). It was just that people started to
develop other languages and/or bytecode compilers in the first half of
the decade, and the results started to appear (and become wider known)
around 2006 when Java6 was published.
However, all these JVM versions share some limitations: the JVM is
statically typed by nature, and up to release 7, did not support dynamic
languages. This has changed with the introduction of
invokedynamic
, a new bytecode instruction which enables method invocation relying on dynamic type checking.
System.out.println("Hello world!");
can be converted to below byte code
0 getstatic #6 <Field java.lang.System.out Ljava/io/PrintStream;>
3 ldc #1 <String "Hello world!">
5 invokevirtual #7 <Method java.io.PrintStream.println(Ljava/lang/String;)V>
8 return
Take example java source Code
void test() {
int i;
for (i = 0; i < 100; i++) {
; // Loop body is empty
}
}
Converts to below byte code
0 iconst_0 // Push int constant 0
1 istore_1 // Store into local variable 1 (i=0)
2 goto 8 // First time through don't increment
5 iinc 1 1 // Increment local variable 1 by 1 (i++)
8 iload_1 // Push local variable 1 (i)
9 bipush 100 // Push int constant 100
11 if_icmplt 5 // Compare and loop if less than (i < 100)
14 return // Return void when done
For For loop main instruction set is
5 iinc 1 1 // Increment local variable 1 by 1 (i++)
8 iload_1 // Push local variable 1 (i)
9 bipush 100 // Push int constant 100
11 if_icmplt 5 // Compare and loop if less than (i < 100)
And then it converts to machine/OS specific instruction