Java Forum / General / September 2006
does bytecode and machine code are same ?
gk - 20 Sep 2006 13:29 GMT does bytecode and machine code are same ?
i am asking in the context of of JVM functionality.
Hi i have the following questions in my mind ....which i dont have answer.....so i have presenting here as a list ......can you please tell me ?
bytecode= .class file (after java file compilation)
(a) what is machine code ?
(b) does bytecode==machine code....same thing ?
(c) what JVM do actually ? does JVM converts byte code to machine code ? or what it does ?
(d) when we compile with javac ---->does JVM invoked ?
(e) when we run with java command -->does JVM invoked ?
Ingo R. Homann - 20 Sep 2006 14:07 GMT Hi,
In short:
> (a) what is machine code ? Some 'binary data' that can be executed by some 'machine'.
> (b) does bytecode==machine code....same thing ? Well 'bytecode' is the machine code for the JVM ('java virtual machine').
> (c) what JVM do actually ? does JVM converts byte code to machine code > ? or what it does ? In interprets some bytecode, it optimizes, it compiles some bytecode to 'native' machine code (for the processor it runs on), it does memory management/garbage collection, ... some very complicated things.
On a different level: It initializes classes and executetes code...
> (d) when we compile with javac ---->does JVM invoked ? Yes.
> (e) when we run with java command -->does JVM invoked ? Yes.
Ciao, Ingo
gk - 20 Sep 2006 14:34 GMT wait a minute please.......i am getting confused now.
so when we compile
javac A.java
JVM is called and a bytecode(.class) file is generated
Now, when we run
java A
what JVM do now ? (i) does it picks up the bytecode and convert into machine code ? (ii) does it picks up the bytecode and convert into machine code and then run that machine code...all three task in one go. ?
i am confused how and when a byte code is converted into machine code and how and when this machine code executes and produce the result ?
> Hi, > [quoted text clipped - 27 lines] > Ciao, > Ingo Ingo R. Homann - 20 Sep 2006 15:08 GMT Hi,
> wait a minute please.......i am getting confused now. > [quoted text clipped - 3 lines] > > JVM is called I'm not completely sure about that (see my answer to Oliver), but I think, yes.
> and a bytecode(.class) file is generated Yes.
> Now, when we run > [quoted text clipped - 6 lines] > i am confused how and when a byte code is converted into machine code > and how and when this machine code executes and produce the result ? Well, early JVMs didnt convert anything to (native) machine code at all - everything was interpreted. Nowadays, JVMs do compile some of the bytecode to native machine code becaus of performance issues( -> HotSpot / JIT ). Not that this is only done for critical sections.
Because of the fact, that the JVM can use runtime-information for optimizing (which e.g. a statical C++-compiler does not have), Java-Code sometimes can run faster that 'native' C++-code.
Note that the internals are *very* complicated... Fortunately you do not have to care about them! :-)
However: If performance is a problem in your java application, then, in 99% of all cases, the problem is *not* the JVM/language, but a bad design/implementation of your application.
Ciao, Ingo
Dijon Yu - 22 Sep 2006 02:58 GMT > wait a minute please.......i am getting confused now. > > so when we compile > > javac A.java Now, you can see like this in A.java, for example:
int a =100,b=120; int c; c = a+b;
> JVM is called and a bytecode(.class) file is generated after javac A.java ,now , class is generated, it include this code:
bipush 100 istore_1 bipush 200 istore_2 iload_1 iload_2 iadd istore_3
just like assembly language, but this instruction is
> Now, when we run > > java A > > what JVM do now ? (i) does it picks up the bytecode and convert into > machine code ? when we run java A, now , this code (or called instruction) will be run by JVM, it is like the assembly run at a real machine, so, we called it Virtual Machine, beacause it is not the final instruction in Machine.
However, who running the JVM, it is Operation System. in different OS, there are different assebly, in windows, it maybe like this :
mov al,[963c] mov bl,[963f] add al,bl
At last, the processor run this, and get the result
Dijon Yu
Oliver Wong - 20 Sep 2006 14:37 GMT >> (d) when we compile with javac ---->does JVM invoked ? > > Yes. Really? How? I thought javac was a C/C++ program.
- Oliver
Ingo R. Homann - 20 Sep 2006 15:01 GMT Hi,
>>> (d) when we compile with javac ---->does JVM invoked ? >> >> Yes. > > Really? How? I thought javac was a C/C++ program. I thought, "javac.exe" is only a small wrapper which starts a JVM and calls sun.compiler.Javac or something like that.
But I might be wrong... ;-)
Ciao, Ingo
Gordon Beaton - 20 Sep 2006 15:02 GMT > Really? How? I thought javac was a C/C++ program. Both "java" and "javac" are written in C, as is the JVM iteslf.
Both programs launch a JVM using JNI_CreateJavaVM().
/gordon
 Signature [ don't email me support questions or followups ] g o r d o n + n e w s @ b a l d e r 1 3 . s e
Thomas Kellerer - 20 Sep 2006 15:03 GMT Oliver Wong wrote on 20.09.2006 15:37:
>>> (d) when we compile with javac ---->does JVM invoked ? >> >> Yes. > > Really? How? I thought javac was a C/C++ program. Yes and no. javac is a wrapper to start a JVM (very similar to java). The actual javac "executable" is implemented in Java (sun.tools.javac.Main). Have a look at the source that come with your JDK. The C sources for the java.exe and javac.exe wrappers are part of that.
Thomas
Chris Uppal - 20 Sep 2006 15:11 GMT > > > (d) when we compile with javac ---->does JVM invoked ? > > > > Yes. > > Really? How? I thought javac was a C/C++ program. Not a chance -- it'd start up a lot faster if it were... (remember IBM's "Jikes" ?)
Of course, it would probably have even more bugs too...
-- chris
Chris - 20 Sep 2006 14:12 GMT Byte code and machine code are similar but different.
Machine Code is the Instruction set that the hardware understands, so for example x86 (Intel/AMD... pc compatible) machines understand the same machine code, while Power Pc (old macs) machines understand a different machine code.
Byte Code is the instruction set a virtual machine understands. MS .Net produces byte code that is essentially the same as our java byte code. Similar to machine code, byte code compiled for the java virtual machine is readable by compatible machines (jvm's), it would not however be readable by the microsoft VM designed to interpret the microsoft byte code.
Yes in short the JVM translates the byte code into machine code, but not directly. This is done through calls to operating system methods. This is why we need different JVM's for different OS's (Mac, PC, *nix)
The java command invokes the JVM... not much else to say about this... cjl
> does bytecode and machine code are same ? > [quoted text clipped - 16 lines] > > (e) when we run with java command -->does JVM invoked ? Sachin - 20 Sep 2006 14:14 GMT (a) Machine code is the code that underatand by the native instruction set of the computer. (eg. RISC & CISC)
(b)No. Byte code deals only with the java virtual computer (java gains platform independence because of this java virtual computer).
(c)Java VM understands byte code. Byte code executes on the JVM instruction set. Which has a stack based architecuture (architecture of the machine instruction set might be different). Threrefore no need (and do not have a meaning) to convert byte code to machine code.
> does bytecode and machine code are same ? > [quoted text clipped - 16 lines] > > (e) when we run with java command -->does JVM invoked ? Chris Uppal - 20 Sep 2006 16:10 GMT > does bytecode and machine code are same ? They are similar in concept but /very/ different in practise.
In both cases they are sequences of instructions from a specific "instruction set". An instruction set is very like a programming language in that it defines exactly what steps the machine should follow to execute some task. Just as programming languages can be /very/ different from each other (perhaps more so than you yet know), instruction set can be very different from each other. As it happens the instruction set, called "Java bytecode", which is used to tell the JVM what to do, is about as different as you can get from the instruction set, called "IA32 machine code" which is used to tell a Pentium processor (or similar) what to do. Still, despite their differences, they are still instruction sets.
Since any instruction set has a well--defined meaning (if you can work it out from the documentation -- which is often difficult), it is /always/ possible to write a program (in whatever programming language you like) which will interpret those instructions and thus, in software, execute the target instructions. That's called a "virtual machine". Similarly it is almost always possible (if you have the money) to create a hardware implementation of the same idea -- it still executes the instructions from the instruction set, but since it's done in hardware (and, even more important, since it is created by people with /staggeringly/ large budgets) it normally will run a lot faster. (But I'll come back to that later).
Now, think of the Java bytecode instruction set. It has an abstract definition, and so someone sitting down to create a JVM only has to follow that definition and they'll produce a correct implementation ("only" !). The thing is that there are /lots/ of different ways that you can produce a correct implementation -- some are easy to write but run slowly, others are less easy to write and run quite a bit faster, some are ridiculously complicated to write and run fastest of all. (Remember that I said that an important reason for hardware to be fast was that the engineers have the budget to create very complicated implementations ? The same thing happens in software -- if you have a large enough budget, and enough /really/ good programmers, then you can create a very fast JVM.)
One effect of that is that you can't ask "how does Java implement bytecodes ?", or even "how does the JVM do it ?". It always depends on exactly /which/ JVM you are talking about.
So, what implementation techniques are available ? The simplest is just a big switch statement rather like this:
for (;;) { int inst = nextInstruction() switch (inst) { case: iadd: // ...do something... break; case: isub: // ...do something... break; // ...and so on for the 200 or so instuctions... } }
That is simple, but it is also slow (probably somewhere between 10 and 20 times slower than we could do if we used more cleverness). But then, it does have some huge advantages too. One is that it is simple to write. Another is that it takes up very little memory since it interprets the Java bytecode directly, and they are fairly compact (perhaps 10 times smaller than "equivalent" IA32 machine code -- although that varies a lot). If I remember correctly, JDK 1.0.2 (a long time ago) used that technique exclusively.
One thing you can do to improve on that is to rewrite the above interpreter loop in assembler -- that will gain you some extra speed (not a huge amount, but some), but is quite a bit harder to do. I think that JDK 1.1 was the first Sun JVM which had its main loop written in assembler.
A different approach would be to translate the bytecode into machine code. Two simple approaches are to do that unconditionally as each class is loaded in, or to wait until a method is executed before translating it (doing "Just In Time" translation -- JITing). That is probably simpler than writing a hand-crafted interpreter loop in assembler, and will run quite a lot faster. The problem is that it takes up a lot of memory for "compiled" (by which I mean: translated into machine code) methods which may never be executed or may be executed only once. Another problem is that although it's not too difficult to translate bytecode into machine code in a simple-minded way, the resulting machine code is nothing like as fast as would be produced by, say, an optimising C compiler. But if we take the time (and invest the development resources) to optimise the machine code well, then the program will spend most of its time optimising stuff, and so it will /still/ seem to run slowly. I think that JDK 1.2 was the first from Sun to use this kind of technique
One obvious improvement would be to combine a simple interpreter with JITing. So you use the slow interpreter for methods which are not called often, and then use faster compiled code for the ones that are. Another possibility would be to translate all methods to machine code before executing them the first time, but only use a quick-and-easy translator at first and reserve the optimising translator for methods which are run often. Or you could combine all three -- use the interpreter the first few times the method was executed, use a simple complier if it is used more often, and use a complicated optimising compiler for code which is executed a lot. That way you don't waste time or space compiling or optimising methods which don't need it, and so can afford to spend a lot more effort on optimising the code that /does/ need it.
That's the approach that Sun use these days. They call their version of it "Hotspot" because it concentrates its optimisation efforts on the hot-spots in the code. It is also massively complicated. That's mostly because optimisation is always complicated (if it isn't complicated then you aren't trying hard enough ;-). But it is also complicated because it has to change code (machine code) while that code is running (and in a thread-safe way), and also has to be able to keep track of what optimisations it has made, and why, so that it can be ready to undo them again if something happens (like a new class being loaded) which might invalidate the assumptions the optimisation was based on.
> (d) when we compile with javac ---->does JVM invoked ? Yes, but only incidentally. the Java compiler, javac, happens to be written in Java, so it the program needs a JVM to run. However, you could create an equivalent compiler (written in a different language) which didn't need a JVM to execute.
> (e) when we run with java command -->does JVM invoked ? Very definitely yes. That's what the java command is /for/. It is, or it contains (however you prefer to think of it) the software implementing the JVM spec.
-- chris
Sachin - 21 Sep 2006 07:12 GMT Hi all,
> > does bytecode and machine code are same ? > [quoted text clipped - 33 lines] > have a large enough budget, and enough /really/ good programmers, then you can > create a very fast JVM.) I think when implementing software a larage budget is spent on it too.... But you can not match with the speed of execution of algorithms on hardware when implemeting same on softwre (which runs by a processor) no matter what programming language is used.
The main reason for this is the taditional Von Neuman architecutre of computing. Need to hold lot of instructions in memeory and accessing memory is the bottle neck (very much slow compare to the speed of the processor).
Also compilers have to map special operators of the program to internal machine instructions, and this adds another overhead. Exection of hardware is faster because,
$ Highly parallel spatial exection $ No extra overhead for interpretation or extra circuitry capable of solving a more general problem.
Regards, Sachin --
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|