Related
I am new to java. I know that the Java virtual machine is an abstract machine which helps to run the Java programs. So I would like to know if the JVM is included with all Java software, such as Eclipse?
Usually not. Java is used by so many programs that including it with every piece of Java software would use a lot more hard drive space than necessary, and a whole new JVM instance would have to be loaded for each one. Also, every piece of software would have to be updated whenever some security flaw is discovered. Hence, it's often installed just once, often shortly after setting up a new computer or OS installation.
Occasionally, a software package may be developed without assuming the presence of Java on a system; hence, it may include its own. Sometimes it may also need a customized JVM of some kind.
The main reason this is done is simply because Java is used by hundreds of millions, if not billions of devices. If a virtual machine or runtime is not so widespread, I can either convince my users to install it (usually an uphill battle if they're not themselves developers) or just bundle it myself.
If you're familiar with the notion of static and dynamic libraries, the same issues crop up there as well.
You may already know that,
the JVM is not one piece of software. Owners have their implementation, but other can make theirs if it satisfies various practical and contractual claims.
and the abstract specification is a Concrete implementations, which exist on many platforms and come from many vendors, are either all software or a combination of hardware and software and runtime instance hosts a single running Java application.
JVM is more to provide a way to strictly define the external behavior (subsystems, memory areas, data types, and instructions) of implementations which are described in an abstract inner architecture.
So To summarize JVM is the combination of hardware and software But not all Java packages are not included as you asked, fairly It doesn't even understand Java source code.
I'm just starting to learn Java (as the second language from Python), but I can't understand the very first point of it. From my understanding, it says:
"Making each kind of compiler (e.g. of C/C++) to each kind of CPU is too much of a hassle. Java, on the other hand, works universally once JVM is installed, because its intermediate code is interpreted by JVM, rather than making a specific native code."
...but don't you need to implement each kind of JVM to each kind of CPU? Is this really an advantage of Java over C/C++?
I think there's a duplicate about this in SO or elsewhere on the internet, but sorry, I couldn't think up any good search word.
each kind of JVM to each kind of CPU is implemented by folks from oracle and other JVM vendors: in case of C/C++ you have to compile YOUR application code for each CPU/OS
Yes, someone has to make a JVM to be able to run on different platforms, but that someone isn't you.
If you go to the download link for Java https://java.com/en/download/manual.jsp you can see there are various JVM builds for Windows, Mac, Linux and Solaris etc
As a programmer, you just have to write your own code and compile it into .class files. Then it's someone else's problem to provide a JVM to run those class files on a specific machine.
Yes someone need to implement each kind of JVM to each kind of CPU? And if this JVM is going to be used, it will also contain a jit compiler, so not much benefit compared to just writing a compiler.
But it might be talking about using the jvm as a target for your own compiled language.
Imagine this: You want to make your own language. Lets call it MyLanguage. Normally you would have to write a compiler, for each cpu, and lots of support code for each operation system you want to support.
But if you just write one compiler which compiles MyLanguage to java bytecode, then the user can run the java byte code on a JVM.
Your language can then be used on any processor/operation system currently supported by a JVM. And you only had to write one compiler.
This is for example what the developers of Scala did.
So up until about 6 months ago, most of my work (big graph processing) consisted of Python and C++. Up to that point, and even now, I had not written any Java whatsoever.. I had seen the language and was familiar with the syntax (having come from a C/C++ background), and liked the idea of the JVM, but never actually written any substantial amount of Java.
When I picked up Scala, I loved it, OOP and functional programming features all in one, and it being on the JVM was great. I've been constantly striving to improve my Scala and have been playing with Akka, and still loving it. However, at times, perhaps it is just me overthinkng it, but I feel I should learn some more about Java and/or the JVM.
I've heard from many that Scala should be considered a separate language from Java, much like C++ to C. Perhaps you may feel the same way, and perhaps learning Java is more or less disjoint from learning Scala, but I'm feeling learning more about the JVM (e.g. JIT compilation, type erasure) would be helpful?
Thoughts?
The JVM executes Bytecode and it is definately helpful to know how this works, just as it is sometimes helpful to know how C/C++ method invocations work or how classes are initialized; because sometimes it matters and cannot be abstracted away.
Java is the prime language for the JVM, and it is helpful to be able to read Java to some extent if you need to use Java classes directly. And this may happen quite often; only a few examples:
you need to use some third party Java library (and there are tons)
working with Properties
you need to do something special in Swing which is not supported by the Scala-Swing wrapper
also sources explaining stuff for 1) will most probably use Java examples
But my advice is not to study it in advance - you'll pick it up when you need it.
Buy this book now: Java Performance. It was only released last October and is a treasure trove of information for anyone who wants to understand the JVM. If you're going to be a Scala developer, you must understand garbage collection and JVM runtime parameters at the very least.
Off top of my head
primitives, autoboxing, and how java arrays are special;
erasure and manifests
how logically tail recursive calls in scala source are compiled
installing -client, -server on your platform and when you want to try 32 bit: e.g. JAVA_HOME and "Java preferences" in OS X. I think openJDK should work anywhere you use same version of Oracle JDK, but IntelliJ warns you to use only official Oracle JDK. I've seen very isolated reports that 3d graphics libs have had problems with openJDK, and also parts of openJDK like the fonts have licensing issues.
setting classpaths in REPL, as compiler option, and in SBT
Hotspot switches, XMX, XMS (heap settings), most common garbage collectors, inlining method calls
java.util.concurrent
possible binary compatibility issues with java and scala code compiled in JDK 6 and 7.
I don't know exactly what you need, but there are several similar questions on SO, look it.
Understanding JVM Better
Understanding the Sun JVM
Also, here good articles for Java Memory Model
Java theory and practice: Fixing the Java Memory Model, Part 1
Java theory and practice: Fixing the Java Memory Model, Part 2
My thought it's better to dig in Java language, write some code, read Java-specific books for better understanding how all things works.
There are a lot of tools surrounding the JVM. If you want to understand how your programs are running (for performance or other reasons) then it's worth being au fait with these. Two useful tools are:
jstack
visualvm
Both are particularly useful for monitoring and interrogating long-running processes.
I think you will know more about JVM when you program Scala. I mean you will have more questions like 'Why this solution is slow and that is fast?' - one way to answer this question is to check the bytecode
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
I wonder how Java is more portable than C, C++ and .NET and any other language. I have read many times about java being portable due to the interpreter and JVM, but the JVM just hides the architectural differences in the hardware, right? We'd still need different JVMs for different machine architectures. What am I missing here? So if someone writes an abstraction layer for C for the most common architectures, let's say the CVM, then any C program will run on those architectures once CVM is installed, isn't it?
What exactly is this portability? Can .NET be called portable?
Portability isn't a black and white, yes or no kind of thing. Portability is how easily one can I take a program and run it on all of the platforms one cares about.
There are a few things that affect this. One is the language itself. The Java language spec generally leaves much less up to "the implementation". For example, "i = i++" is undefined in C and C++, but has a defined meaning in Java. More practically speaking, types like "int" have a specific size in Java (eg: int is always 32-bits), while in C and C++ the size varies depending on platform and compiler. These differences alone don't prevent you from writing portable code in C and C++, but you need to be a lot more diligent.
Another is the libraries. Java has a bunch of standard libraries that C and C++ don't have. For example, threading, networking and GUI libraries. Libraries of these sorts exist for C and C++, but they aren't part of the standard and the corresponding libraries available can vary widely from platform to platform.
Finally, there's the whole question of whether you can just take an executable and drop it on the other platform and have it work there. This generally works with Java, assuming there's a JVM for the target platform. (and there are JVMs for many/most platforms people care about) This is generally not true with C and C++. You're typically going to at least need a recompile, and that's assuming you've already taken care of the previous two points.
Yes, if a "CVM " existed for multiple platforms, that would make C and C++ more portable -- sort of. You'd still need to write your C code either in a portable way (eg: assuming nothing about the size of an int other than what the standard says) or you'd write to the CVM (assuming it has made a uniform decision for all of these sorts of things across all target platforms). You'd also need to forgo the use of non-standard libraries (no networking, threading or GUI) or write to the CVM-specific libraries for those purposes. So then we're not really talking about making C and C++ more portable, but a special CVM-C/C++ that's portable.
Once again, portability isn't a black and white thing. Even with Java there can still be incompatibilities. The GUI libraries (especially AWT) were kind of notorious for having inconsistent behavior, and anything involving threads can behave differently if you get sloppy. In general, however, it's a lot easier to take a non-trivial Java program written on one platform and run it on another than it is to do the same with a program written in C or C++.
As others have already said, portability is somewhat of a fuzzy concept. From a certain perspective, C is actually more portable than Java. C makes very few assumptions about the underlying hardware. It doesn't even assume that there are 8 bits in a byte, or that negative numbers should be represented using two's complement. Theoretically, as long as you have a Von Neumann based machine and a compiler, you're good to go with C.
In fact, a "Hello world" program written in C is going to work on many more platforms than a "Hello world" program written in Java. You could probably get the same "hello world" program to work on a PDP-11 and an iPhone.
However, the reality is that most real-world programs do a lot more than output "Hello world". Java has a reputation for being more portable than C because in practice, it takes a lot more effort to port real-world C programs to different platforms than real-world Java programs.
This is because the C language is really ANSI-C, which is an extremely general-purpose, bare-bones language. It has no support for network programming, threading, or GUI development. Therefore, as soon as you write a program which includes any of those things, you have to fall back on a less-portable extension to C, like Win32 or POSIX or whatever.
But with Java, network programming, threading, and GUI tools are defined by the language and built into each VM implementation.
That said, I think a lot of programmers also underestimate the progress modern C/C++ has made in regard to portability these days. POSIX goes a long way towards providing cross-platform threading, and when it comes to C++, Boost provides networking and threading libraries which are basically just as portable as anything in Java. These libraries have some platform-specific quirks, but so does Java.
Essentially, Java relies on each platform having a VM implementation which will interpret byte code in a predictable way, and C/C++ relies on libraries which incorporate platform specific code using the preprocessor (#ifdefs). Both strategies allow for cross platform threading, networking, and GUI development. It's simply that Java has made faster progress than C/C++ when it comes to portability. The Java language spec had threading, networking and GUI development almost from day one, whereas the Boost networking library only came out around 2005, and it wasn't until 2011 with C++11 that standard portable threading was included in C++.
When you write a Java program, it runs on all platforms that have JVM written for them - Windows, Linux, MacOS, etc.
If you write a C++ program, you'll have to compile it specifically for each platform.
Now, it is said that the motto of Java "write once, run everywhere" is a myth. It's not quite true for desktop apps, which need interaction with many native resources, but each JavaEE application can be run on any platform. Currently I'm working on windows, and other colleagues are working on Linux - without any problem whatsoever.
(Another thing related to portability is JavaEE (enterprise edition). It is said that applications written with JavaEE technologies run in any JavaEE-certified application server. This, however, is not true at least until JavaEE6. (see here))
Portability is a measure for the amount of effort to make a program run on another environment than where it originated.
Now you can debate if a JVM on Linux is a different environment than on Windows (I would argue yes), but the fact remains that in many cases there is zero effort involved if you take care of avoiding a few gotchas.
The CVM you are talking about is very much what the POSIX libraries and the runtime libraries try to provide, however there are big implementation differences which make the hurdles high to cross. Certainly in the case of Microsoft and Apple these are probably intentionally so in order to keep developers from bringing out products on competing platforms.
On the .net front, if you can stick to what mono provides, an open source .Net implementation, you will enjoy roughly the same kind of portability as Java, but since mono is significantly behind the Windows versions, this is not a popular choice. I do not know how popular this is for server based development where I can imagine it is less of an issue.
Java is portable from the perspective of the developer: code written in Java can be executed in any environment without the need to recompile. C is not portable because not only is it tied to a specific OS in many cases, it is also always tied to a specific hardware architecture once it has been compiled. The same is true for C++. .Net is more portable than C/C++, as it also relies on a virtual machine and is therefore not tied to a specific hardware architecture at compile-time, but it is limited to Windows machines (officially).
You are correct, the JVM is platform-specific (it has to be!), but when you say Java is portable, you are talking about it from a developer standpoint and standard Java developers do not write the JVM, they use it :-).
Edit #Raze2Dust To address your question. Yes, you could. In fact, you could make Java platform-specific by writing a compiler that would generate machine code rather than bytecode. But as some of the other comments suggest, why would you do that? You'd have to create an interpreter that maps the compiled code to operations in the same way the JVM works. So the long and short of it is, absolutely, you definitely could, but why would you?
Java provides three distinct types of portability:
Source code portability: A given Java program should produce identical results regardless of the underlying CPU, operating system, or Java compiler.
CPU architecture portability: the current Java compilers produce object code (called byte-code) for a CPU that does not yet exist. For each real CPU on which Java programs are intended to run, a Java interpreter, or virtual machine, "executes" the J-code. This non-existent CPU allows the same object code to run on any CPU for which a Java interpreter exists.
OS/GUI portability: Java solves this problem by providing a set of library functions (contained in Java-supplied libraries such as awt, util, and lang) that talk to an imaginary OS and imaginary GUI. Just like the JVM presents a virtual CPU, the Java libraries present a virtual OS/GUI. Every Java implementation provides libraries implementing this virtual OS/GUI. Java programs that use these libraries to provide needed OS and GUI functionality port fairly easily.
See this link
You ask if one could write a "C VM". Not exactly. "Java" is a big term used by Sun to mean a lot of things, including both the programming language, and the virtual machine. "C" is just a programming language: it's up to the compiler and OS and CPU to decide what format the resulting binary should be.
C is sometimes said to be portable because it doesn't specify the runtime. The people who wrote your compiler were able to pick things that make sense for that platform. The downside is that C is low-level enough, and platforms are different enough, that it's common for C programs to work fine on one system and not at all on another.
If you combine the C language with a specific ABI, you could define a VM for it, analogous to the JVM. There are a few things like this already, for example:
The "Intel Binary Compatibility Specification" is an example of such an ABI (which almost nobody uses today)
"Microsoft Windows" could also be such an ABI (though a huge and underspecified one), for which Wine is one VM that runs programs written for it
"MS-DOS", for which dosemu is one VM
"Linux" is one of the more popular ones today, whose programs can be run by Linux itself, NetBSD, or FreeBSD
"PA-RISC", for which HP's Dynamo was a JIT-like VM
All of these C VMs are in fact a real machine -- nobody, AFAIK, has ever made a C VM that was purely virtual. This isn't surprising, since C was designed to run efficiently on hardware, so you might as well make it run normally on one system. As HP showed, you can still make a JIT to run the code more efficiently, even on the same platform.
You need the JVM for different architectures, but of course your Java programs run on that JVM. So once you have a JVM for an architecture, then your Java programs are available for that architecture.
So I can write a Java program, compile it down to Java bytecode (which is architecture-agnostic), and that means I can run it on any JVM on any architecture. The JVM abstracts away the underlying architecture and my program runs on a virtual machine.
The idea is that the Java language is portable (or more accurately, the compiled byte-code is portable). You are correct that each VM requires a specific implementation for a given hardware profile. However, once that effort has been made, all java bytecode will run on that platform. You write the java/bytecode once, and it runs on any JVM.
.NET is quite similar, but with a far lower emphasis on the principle. The CLR is analogous to the JVM and it has its own bytecode. Mono exists on *nix, but you are correct that it is not "official".
Portability or as written in Wikipedia, Software Portability is the ability to reuse the same software (code) across multiple environments (OSes). The java JVM is a JVM that can be run on any operating systems it was designed for: Windows, Linux, Mac OSes, etc.
On .NET, it is possible to port your software to different platforms. From Wikipedia:
The design of the .NET Framework
allows it to theoretically be platform
agnostic, and thus cross-platform
compatible. That is, a program written
to use the framework should run
without change on any type of system
for which the framework is
implemented.
And because Microsoft never implemented the .NET framework outside of Windows and seeing that .NET is platform agnostic, Mono has made it possible to run .NET applications and compile code to run in Linux.
For languages such as C++, Pascal, etc. you will have to go to each OS and build it on that platform in order to run it on that platform. The EXE file in Windows isn't the same as the .so in linux (the machine code) since both uses different libraries to talk to the kernel and each OS has its own kernel.
WORE - Write Once Run Everywhere
In reality, this is limited to the platforms that have a JVM, but this covers off the majority of platforms you would wish to deploy to. It is almost a half-way between an interpreted language, and a compiled language, gaining the benefits of both.
Where do JVM Implementations differ (except licensing)?
Does every JVM implement Type Erasure for the Generic handling?
Where are the differences between:
JRockit
IBM JVM
SUN JVM
Open JDK
Blackdown
Kaffe
.....
Deals one of them with Tail-Call-Optimization?
JVM implementations can differ in the way they implement JIT compiling, optimizations, garbage collection, platforms supported, version of Java supported, etc. They all must meet set of features and behaviors so that it will execute your Java bytecodes correctly.
As you've pointed out, the major difference tends to be in licensing. Other non-technical differences tend to be in free/paid support options, integration with other technologies (usually J2EE servers), and access to source code.
Note: While a J2EE server runs on the JVM, some servers have integrated tools for monitoring, analyzing, and tweaking JVM performance.
As far as technical differences, those have grown less significant over the years. Once upon a time, the IBM and JRockit JVM's had far superior performance to the reference Sun implementation. This was due to significant differences in the types of runtime optimizations, differences in garbage collection, and differences in native-code (and how much native code various classes uses). These performance differences aren't as significant anymore.
Some JVM's also include or integrate with diagnostics and monitoring tools. JRockit includes a set of tools for monitoring your JVM performance. Sun provides various JMX-based tools with overlapping features to do the same. IBM Websphere once upon a time included a similar set of tools for their whole J2EE application server (not sure if they still do, but I would assume that's still true)...
Some of the open source JVM's tend to have a little slower performance because they have been redeveloped from the ground up. As such, they've got a bit more catching up to do. Last I checked about 2 years ago, Blackdown was significantly slower (1.5x-2x?) than the Sun JVM. It was also a bit behind of supported versions of Java.
Type erasure is a compiler function and as such JVM independent.
Things like type erasure are done by the compiler to be backward compatible with older JVMs. Most JVMs should support all the features you need, but some may be more optimized than others. I'm guessing the Sun JVM is probably the fastest.
JIT compiling is one thing that some JVM:s don't have.
If the JVM claims to be Java it must pass the TCK, providing a lot of stock funcitonaltiy.
The differences are in non-core places, like garbage collection, the jconsole/visualvm in the Sun JVM, precompilation etc.
clarification: TCK is the test suite that a virtual machine has to pass in order to be officially Java compliant.
Another difference between JVMs is behaviour on undocumented API. (e.g. com.sun.xxx)
For example, Sun's JVM and IBM's JVM both have slightly different behaviour on signal handling. (IBM's JVM doesn't allow the application to trap the "INT" signal in certain cases.)
JVM is like a virtual Machine that works to Load the class and Bytcode varifier, execute the code. while Applocaion Programming Interface is Collection of Packages. and Packages are collection of class. Java program execute where JVM Installed and Works.
Tail-call optimization is not yet supported by Java. John Rose is leading efforts to include this in a future release, and has described the approach, and some of the issues involved.