I know java generates bytecode but the JVM needs to interpret it everytime during runtime.
Does a compiler exist that generates machine independent code, lets say for C.
Then at a target machine this is permanently converted to its local machine code once rather than converting for each run?
Does this solve why many developers develop for windows but no linux?
Not really, but some stuff comes close.
C is regarded as low level as possible while being portable by some. (This, of course, excludes all APIs). The GHC Haskell compiler uses internally a very c-like language in that regard c--, that might be very close to the machine in depended code you are looking for.
Most modern compilers do have such intermediate Code, for example LLVM. There is even a assembler like (so even more low leven than C) for that. But note that LLVM intermediate code is not portable, as for example the pointer size has to be known at compile time. (all the sizeofs in C will fixed at this time)
But there is a IMO more simple solution: Compile the code for any platform, and if you are on a different platform you a dynamic recompiler like QEMU. That still does negatively impact performance.
It's certainly possible, and interpreters exist for C and C++. However, projects using these languages will often use platform-specific code (like the Windows APIs) which stops them from being portable. Interpreted languages generally supply platform-independent core libraries.
Modern compilers – like Clang, LLVM and GCC – all compile your source code to an intermediate language. This means that the same code-level optimizations can be applied to any language that the compiler can convert, and it also enables tools like Emscripten which can effectively compile C to JavaScript! I believe it was used for the recent JavaScript Unreal Engine demo.
A Java example: Android 4.4 introduced a new experimental runtime virtual machine, ART (Android Runtime).
ART straddles an interesting mid-ground between compiled and interpreted code, called ahead-of-time (AOT) compilation. Currently with Android apps, they are interpreted at runtime (using the JIT), every time you open them up. This is slow. (iOS apps, by comparison, are compiled native code, which is much faster.) With ART enabled, each Android app is compiled to native code when you install it. Then, when it’s time to run the app, it performs with all the alacrity of a native app.
Source
Related
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 isn't C/C++ called platform independent like java when the same source code written in C/C++ can be made to run on different operating systems by different compilers, just like JVM is used in java.
Isn't different compilers and JVM doing same thing and achieving platform independence.
Isn't different compilers and JVM doing same thing and achieving platform independence.
Not really. Your Java program is running within the JVM, which acts as a translation layer between the Java byte code and the native machine code. It hides the platform-specific details from the Java application code.
This is not the case with C. C code (typically) runs natively, so there is no translation layer isolating it from platform-specific details. Your C code can be directly affected by platform-specific differences (word sizes, type representations, byte order, etc.).
A strictly conforming C program, which uses nothing outside of the standard library and makes no assumptions about type sizes or representation beyond the minimums guaranteed by the language standard, should exhibit the same behavior on any platform for which it is compiled. All you need to do is recompile it for the target platform.
The problem is that most useful real-world C and C++ code isn't strictly conforming; to do almost anything interesting you have to rely on third-party and system-specific libraries and utilities, and as soon as you do you lose that platform independence. I could write a command-line tool manipulates files in the local file system that would run on Windows and MacOS and Linux and VMS and MPE; all I would need to do is recompile it for the different targets. However, if I wanted to write something GUI-driven, or something that communicated over a network, or something that had to navigate the file system, or anything like that, then I'm reliant on system-specific tools and I can't just rebuild the code on different platforms.
It's not the language itself that is platform dependent. It's possible to compile both C and C++ for JVM, but it's not very common to do so. Compiling C++ for the JVM
In the same way, it is possible to compile Java for a specific target instead of JVM. Compiling java source code to native exe
But Java and JVM are both designed to work together, so that combination is very natural to use.
C is designed to be very close to the hardware. There's not really a reason to use C if your target is JVM. Then use Java instead.
In theory, you can compile ANY language for ANY target, as long as the target is turing complete.
Sidenote: Don't write "C/C++". They are completely different languages.
In case of C or C++ (language that are not platform independent), the compiler generates an .exe file which is OS dependent. When we try to run this .exe file on another OS it does not run, since it is OS dependent and hence is not compatible with the other OS.
Isn't different compilers and JVM doing same thing and achieving platform independence.
The JVM per se is the platform. It is abstracting away, whether it is ARM/AMD64/...
C/C++ is getting compiled. It may only run on the processor(family) that it was compiled for.
You can't just take a binary for MIPS and execute it on ARM.
Compare it:
[C(++)]
|
v
[Processor]
vs
[Java (Classfiles)]
|
v
[JVM] #Abstraction layer
|
v
[Processor]
The role of JVM in the independent platform is that it acts as a virtual processor. when we used c/c++ to compiler different processor converts the source code into a different binary pattern that's why there are not platform-independent.
C++ language itself doesn't assume any specific platform, so in that sense it is platform independent.
I had this question in software course:
True/False: The Java interpreter converts files from a byte-code format to executable files.
I think the statement is false. In class, they said the interpreter "executes" the byte-code files, on the system using the JVM (I didn't listen too much but I think I got it fairly correctly), but as I understood, it doesn't actually convert it to executable files (which presumably are .exe files), just runs it on the system directly.
"True/False: The Java interpreter converts files from a byte-code format to executable files".
The answer is false1.
The Java interpreter is one of the two components of the JVM that is responsible for executing Java code. It does it by "emulating" the execution of the Java Virtual Machine instructions (bytecodes); i.e. by pretending to be a "real" instance of the virtual machine.
The other JVM component that is involved is the Just In Time (JIT) compiler. This identifies Java methods that have been interpreted for a significant amount of time, and does an on-the-fly compilation to native code. This native code is then executed instead of interpreting the bytecodes.
But the JIT compiler does not write the compiled native code to the file system. Instead it writes it directly into a memory segment ready to be executed.
Java's interpret / JIT compile is more complicated, but it has a couple of advantages:
It means that it is not necessary to compile bytecodes to native code before the application can be run, which removes a significant impediment to portability.
It allows the JVM to gather runtime statistics on how the application is functioning, which can give hints as to the best way to optimize the native code. The result is faster execution for long-running applications.
The downside is that JIT compilation is one of the factors that tends to make Java applications slow to start (compared with C / C++ for example).
1 - ... for mainstream Java (tm) compilers. Android isn't Java (tm)2. Note that the first version of Java was interpreter only. I have also seen Java (not tm) implementations where the native code compilers were either ahead-of-time or eager ... or a combination of both.
2 - You are only permitted by Oracle to describe your "java-like" implementation as Java(tm) if it passes the Java compliance tests. Android wouldn't.
The Java compiler converts the source code to bytecode. This bytecode is then interpreted (or just-in-time-compiled and then executed) by the JVM. This bytecode is a kind of intermediate language that has not platform dependence. The virtual machine then is the layer that provides system specific functionality.
It is also possible to compile Java code to native code, a project aiming this is for example the GCJ.
To answer your question: no, a normal Java compiler does not emit an executable binary, but a set of classes that can be executed using a JVM. You can read more about this on Wikipedia.
False for regular JVMs. No executable files are created. The conversion from bytecode to native code for that platform takes place on the fly during execution. If the program is stopped, the compiled code is gone (was in memory only).
The new Android JVM ART does compile the bytecode into executables before to have better startup and runtime behavior. So ART creates files.
ART straddles an interesting mid-ground between compiled and interpreted code, called ahead-of-time (AOT) compilation. Currently with Android apps, they are interpreted at runtime (using the JIT), every time you open them up. This is slow. (iOS apps, by comparison, are compiled native code, which is much faster.) With ART enabled, each Android app is compiled to native code when you install it. Then, when it’s time to run the app, it performs with all the alacrity of a native app. http://www.extremetech.com/computing/170677-android-art-google-finally-moves-to-replace-dalvik-to-boost-performance-and-battery-life
The answer is false
reason:
JIT-just in time compiler and java interpreter does a same thing in different way but as per performance JIT wins. The main task is to convert the given bytecode into machine dependent Assembly language as of abstract information.Assembly level language is a low level language which understood by machine's assembler and after that assembler converts it to 01010111.....
On the EN Wiki I read that both C# and Java are interpreted languages, however at least for C# I think it is not true.
Many interpreted languages are first compiled to some form of virtual
machine code, which is then either interpreted or compiled at runtime
to native code.
From my understanding, it is compiled into CIL and when run, using JIT its compiled to target platform. I have also read that JIT is an interpreter, is that really so?
Or are they called interpreted as they are using intermediate code? I do not understand it.
Thanks
JIT is a form of compilation to native (machine) code. Typically (but not as a necessity), implementations of either the CLI and JVM are compiled in two steps:
the language compiler compiles code to something intermediate (IL/bytecode)
the JIT compiles that to native/machine code at runtime
However, interpreters for both do exist. Micro Framework operates as an IL interpreter, for example. Equally, tools like (looking .NET here) NGEN and "AOT" (mono) allow compilation to native/machine code at the start.
They are considered JIT languages which is different from interpreting. JIT simply compiles to native code when needed during execution. The common strategy is to compile into an intermediate representation (bytecode) beforehand which makes the JIT faster.
However, there is nothing that prevents them from being interpreted, or even statically compiled. Languages are simply languages - how they are executed is irrelevant from a language perspective.
On the EN Wiki I read that both C# and Java are interpreted languages
Can you pls provide the link?
May be the interpreted word means different here. It perhaps means that these languages are first interpreted to convert source code into platform-independent code.(VM Specific)
are they called interpreted as they are using intermediate code
I too think so.
I have also read that JIT is an interpreter
JIT is a compiler. See this
Is something "interpreter" or not depends on context of discussion.
From purely abstract view interpreter can be defined as any intermediate program present in runtime which dynamically translates program code written in one language to a target code of hardware/software of other language. Think about runing java bytecode on x86 hardware, or running Python on CLR VM what exactly IronPython is. In this view every virtual machine is an interpreter of some kind. As it is program present in runtime it clearly differs from static compilers or hardware implemented VM-s.
Now there are many different ways to achieve this functionality where accent is on "dynamically" and "present in runtime".
In discussions where implementation of VM matters, people make clear distinction between "classical" interpreter and JIT-ed one. Classical interpreter is something which for every instruction of hosted program emits routine of target code. This design is simple to build, but hard to optimize. JIT-ed design reads bunch of instruction of original code, and then translates all those instructions to a one native compiled routine. So it "interprets" faster. It is like micro static compiler within VM. There are many different ways to accomplish behavior labeled as JIT, and then there are other approaches like tracing compilers.
Modern VM's like CLR, HotSpot and J9 JVM's are even more complex than to be tagged with simple labels as JIT or Interpreter. They can be at a same time static compilers (AOT execution), classical interpreters and JIT-ed VMs.
For example CLR can compile code Ahead-Of-Time (static compiler), and store native code as bunch of more or less excutable files on disk to be used for faster future startups of hosted program. I believe "ngen" is AOT process used in windows for this functionality. If AOT is not used CLR behaves as JIT VM.
J9 and HotSpot are able to switch in runtime between purely interpreted execution or JIT-ed on depending of code analysis and current load. So it's is quite gray area. J9 even has AOT functionality similar to CLR.
Some other VMs like Maxine JVM or PyPy are socalled "metacircular" VM. This means they are (mostly) implemented in a same language they host (Maxine is JVM written in Java). In order to provided good code they usually have some JIT like behavior implemented in host language which is than bootstrapped and optimized by a very low, close to machine, interpreter.
So actual definition of interpreter varies on context of discussion. When labels like JIT are used then there is clear accent of discussion to an implementation details of VM being discussed.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why isn't more Java software compiled natively?
I know that Java is byte code compiled, but when using the JIT, it will compile the 'hotspots' to native code. Why is there not an option to compile a program to native code?
There is an option to compile Java source code files in binary code it is called GCJ and come from Free Software Foundation.
It is not officially supported by Sun/Oracle but i've used the compiler and it do a great job ;)
Java, as a language, can be implemented, like any language, in many ways. This include full interpretation, bytecode compilation, and native compilation. See Java language specification
The VM specification defines how bytecode should be loaded and executed. It defines the compiled class format, and the execution semantics, e.g. threading issue, and what is called the "memory model". See Java VM specification
While orignally meant to go together, the language and the VM are distinct specifications. You can compile another language to Java bytecode and run it on top of the JVM. And you can implement the Java language in different way, notably without a VM, as long as you follow the expected semantics.
Of course, both are still related, and certain aspects of Java might be hard to support without bytecode interpretation at all, e.g. custom ClassLoader that return bytecode (see ClassLoader.defineClass). I guess the bytecode would need to be JIT'ed immediatly into native code, or maybe are not supported at all.
Which platform native code should it compile to?
Windows, Mac, Linux?
What if the developer works on a different platform than the application is going to run on?
What if the application platform changes, either in the server room or on the desktop?
I don't see the benefit, the JVM's nowadays seem to be to be fast enough for very general purpose needs.
There are several products out there to compile java programs to native code, however they are imperfect, and not at all like the JIT compiler. Some differences include:
Write Once Run Everywhere - it will only work on the target you compile it for.
Dynamic code - you cannot load jars or other Java code at runtime, which is often a feature of application servers, GUI builders and the like.
Runtime profiling - a lot of JIT compiler action involves understanding what the code is doing at runtime, not what it could potentially do under a static analysis, meaning that JIT can outperform a natively compiled application in the right circumstances.
Cannot support all Java features. Things like reflection aren't going to be very meaningful in a compiled program.
Large footprint - when it is compiled to native code, all of the libraries the JVM gives you have to be bundled into the package, causing a very large footprint. It is a tricky problem to figure out what can be left out.
So it is possible, for a certain subset of applications, to compile to native code, but as VMs have gotten faster and faster, and issue #5 above has not really been improved (although project Jigsaw should help with that), it is not a very compelling option for real world applications.
Because it is enough to have byte-code compiled.
If you would compile your own code - you had also compile all libraries.
And it is real problem from two point of view:
1. licensing - most of the code wouldn't be changed
2. you had 'recompile' megatons of code :-)
This was a decision made by Sun to not allow this because they wanted to position Java as being inherently multi-platform. As such, they wanted to ensure that any Java application compiled would run on any platform with a JVM. This prevents there from being Java binaries available on-line which don't run on certain hardware or operating systems.