What is the difference between DVM and JVM? - java

What is difference between Java Virtual Machine and Dalvik Virtual Machine?

DVM is Register based which is designed to run on low memory, uses its own byte code and runs .Dex file
JVM is Stack based which uses java byte code and runs .class file having JIT.
Java source code is compiled by the Java compiler into .class files.
Then the dx (dexer) tool, part of the Android SDK processes the .class files into a file format called DEX that contains Dalvik bytecode.
The dx tool eliminate all the redundant information that is present in the classes.
In DEX all the classes of the application are packed into one file.
DVM has been designed so that a device can run multiple instances of the VM efficiently.
stack-based machines must use instructions to load data on the stack and manipulate that data, and, thus, require more instructions than register machines to implement the same high level code, but the instructions in a register machine must encode the source and destination registers and, therefore, tend to be larger.

Conceptually, there is little
difference from an application level
between a DVM and a JVM.
Architecturally, there is a major
difference between the registerbased
DVM and the stack-based JVM.
Both use a VM code model. However, the
DVM uses registerbased opcodes that
are comparable to the register-based
bytecode instructions that most of the
target platforms already execute. This
includes architectures such as those
available from ARM and MIPS and the
x86-compatible architectures from
Intel, AMD, and VIA Technologies.
Google developed Android and chose DVM
for several reasons. First, there were
licensing issues with most JVMs. Next,
the DVM should be more efficient in
terms of memory usage and performance
on a register-based machine. DVM is
also supposed to be more efficient
when running multiple instances of the
DVM. Applications are given their own
instance. Hence, multiple active
applications require multiple DVM
instances. Like most Java
implementations, the DVM has an
automatic garbage collector.
More about it

The jvm architecture is stack-based whereas the dvm architecture is register-based. Stack-based machines require more instructions(i.e. larger instruction set) than register-based machines for the same task. On the other side, each instruction in the register-based machines are larger.

When a Java virtual machine start running a program, it needs memory to store
many things, including bytecodes and other information it extracts
from loaded class files, objects the program instantiates, parameters to
methods, return values, local variables, and intermediate results of computations.
The Java virtual machine organizes the memory it requires to execute a program
into several runtime data areas.
Generally, stack-based machines must use instructions to load data on the stack
and manipulate that data, and, thus, require more instructions than
register machines to implement the same high level code, but the instructions
in a register machine must encode the source and destination registers
and, therefore, tend to be larger.
This difference is primarily of importance to VM interpreters for whom opcode
dispatch tends to be expensive and other factors are relevant for JIT Compilation.
Being optimized for low memory requirements, Dalvik has some specific characteristics
that differentiate it from other standard VMs>>>>>
The VM was just slimmed down to use less space--->>
Dalvik currently has no just-in-time-compiler (JIT), but Android 2.0
includes experimental source for one (disabled by default).
The constant pool has been modified to use only32-bit indexes to simplify
the interpreter. It uses its own bytecode, not Java bytecode***

Dalvik VM can't execute Java bytecode(.class) It has to be(.dex)
Oracle JVM has stack based architecture & Dalvik has register based architecture.
JVM suppost to multiple operating system. (it is open source) but DVM supported for Android Operating system (before comming android 5.o android used the DVM)

Here is a tabular comparison(Source: Mr. Atul):

Jvm will work based on byte code and the dvm will works based on optimized bytecode it is optimised for mobile platforms because mobile devices have low memory and low process that's why it is using the linux kernal.

Here, We can get the basic difference among the JVM (Java Virtual Machine) and DVM (Dalvik Virtual Machine).
From figure it is obvious that DVM can run only .dex files. Dex compiler takes all .class (can be executed by JVM) files for all the classes belongs to application and convert all of them into a single .dex file. Later .dex file is executed by DVM. Additionally, .class files resulted by Javac (java compiler) from .java->.class.

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.

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.

Does javac perform any bytecode level optimizations depending on the underlying operating system?

My understanding is that the Java bytecode produced by invoking javac is independent of the underlying operating system, but the HotSpot compiler will perform platform-specific JIT optimizations and compilations as the program is running.
However, I compiled code on Windows under a 32 bit JDK and executed it on Solaris under a 32 bit JVM (neither OS is a 64 bit operating system). The Solaris x86 box, to the best of my knowledge (working to confirm the specs on it) should outperform the Windows box in all regards (number of cores, amount of RAM, hard disk latency, processor speed, and so on). However, the same code is running measurably faster on Windows (a single data point would be a 7.5 second operation on Windows taking over 10 seconds on Solaris) on a consistent basis. My next test would be to compile on Solaris and note performance differences, but that just doesn't make sense to me, and I couldn't find any Oracle documentation that would explain what I'm seeing.
Given the same version (major, minor, release, etc.) of the JVM on two different operating systems, would invoking javac on the same source files result in different optimizations within the Java bytecode (the .class files produced)? Is there any documentation that explains this behavior?
No. javac does not do any optimizations on different platforms.
See the oracle "tools" page (where javac and other tools are described):
Each of the development tools comes in a Microsoft Windows version (Windows) and a Solaris or Linux version. There is virtually no difference in features between versions. However, there are minor differences in configuration and usage to accommodate the special requirements of each operating system. (For example, the way you specify directory separators depends on the OS.)
(Maybe the Solaris JVM is slower than the windows JVM?)
The compilation output should not depend on OS on which javac was called.
If you want to verify it try:
me#windows# javac Main.java
me#windows# javap Main.class > Main.win.txt
me#linux# javac Main.java
me#linux# javap Main.class > Main.lin.txt
diff Main.win.txt Main.lin.txt
I decided to google it anyway. ;)
http://java.sun.com/docs/white/platform/javaplatform.doc1.html
The Java Platform is a new software platform for delivering and running highly interactive, dynamic, and secure applets and applications on networked computer systems. But what sets the Java Platform apart is that it sits on top of these other platforms, and executes bytecodes, which are not specific to any physical machine, but are machine instructions for a virtual machine. A program written in the Java Language compiles to a bytecode file that can run wherever the Java Platform is present, on any underlying operating system. In other words, the same exact file can run on any operating system that is running the Java Platform. This portability is possible because at the core of the Java Platform is the Java Virtual Machine.
Written April 30, 1996.
A common mistake, esp if you have developed for C/C++, is to assume that the compiler optimises the code. It does one and only one optimisation which is to evaluate compiler time known constants.
It is certainly true that the compiler is no where near as powerful as you might imagine because it just validates the code and produces byte-code which matches your code as closely as possible.
This is because the byte-code is for an idealised virtual machine which in theory doesn't need any optimisations. Hopefully when you think about it that way it makes sense that the compiler does do anything much, it doesn't know how the code will actually be used.
Instead all the optimisation is performed by the JIT in the JVM. This is entirely platform dependant and can produce 32-bit or 64-bit code and use the exact instruction of the processor running the code. It will also optimise the code based on how it is actually used, something a static compiler cannot do. It means the code can be re-compiled more than once based on different usage patterns. ;)
To my understanding javac only consideres the -target argument to decide what bytecode to emit, hence there is no platform specific in the byte code generation.
All the optimization is done by the JVM, not the compiler, when interpreting the byte codes. This is specific to the individual platform.
Also I've read somewhere that the Solaris JVM is the reference implementation, and then it is ported to Windows. Hence the Windows version is more optimzied than the Solaris one.
Does javac perform any bytecode level optimizations depending on the
underlying operating system?
No.
Determining why the performance characteristics of your program are different on two platforms requires profiling them under the same workload, and careful analysis of method execution times and memory allocation/gc behaivor. Does your program do any I/O?
To extend on dacwe's part "Maybe the Solaris JVM is slower than the windows JVM?"
There are configuration options (e.g., whether to use the client or server vm [link], and probably others as well), whose defaults differ depending on the OS. So that might be a reason why the Solaris VM is slower here.

Is the DVM an interpreter or a Compiler?

Is the DVM an interpreter or a compiler? Why did google have to come up with the DVM when there is already the JVM? Can the JVM not be used in mobile platforms? If not why not?
Is the DVM an interpreter or a
compiler?
There's a tool called dx that converts your java bytecode to a dex file. So, you compile with java to create a java bytecode (a class file) and a dx tool converts these bytecodes to a .dex file (executable).
Why did google have to come up with
the DVM when there is already the JVM?
Dalvik is optimised to run on mobile devices or devices with low memory requirement. Dalvik VM takes less space to run compared to the JVM.
One important factor is LICENSE. If Google had to go to J2ME, the application had to be licensed, etc and Google wanted to avoid being licensed.
Also a quote from #leo's - Is Dalvik the better J2ME?:
As J2ME is not really a strong
framework, you have a single
programming language, but it's up to
the vendor which functionality he
likes to integrate, every single phone
is different. That makes porting J2ME
to a real pain.
3)
Can the JVM not be used in mobile
platforms? If not why not?
At the present moment, no as it requires resources (that's available on PC) to run. Also, it's a stack machine, so it uses "instructions to load data on the stack and manipulate that data, and, thus, require more instructions than register machines to implement the same high level code" (source).
We can expect future mobile/portable devices to be able to have the processing power, storage capability and security features to run the JVM, but for now, Dalvik is king! :-)
Hope this helps.
DVM = Interpreter wiki
Dalvik is very optimized and has different architecture to support Android features. Do look at the wiki link above you will have answers for everything.
JVM can be used in mobile platforms. Infact, J2ME is based on JVM.
Is the DVM an interpreter or a
compiler?
Given that the version of Dalvik that shipped with 2.2 has just-in-time compilation, the answer is "yes."
Why did google have to come up with
the DVM when there is already the JVM?
Can the JVM not be used in mobile
platforms? If not why not?
When you say "the" JVM, I'll assume you mean Sun's* JVM. There's no reason why it can't be used in a mobile platform, and it has been. ("Mobile" being a very broad term.) However, that particular implementation is not ideal in every environment, and Java was always intended to have many ways to run its bytecode ranging from VMs on desktops to silicon that runs it directly.
Exactly what drove the decision to implement Dalvik is a question only the people who wrote it can answer, although it may have come down to licensing or having the ability to fine-tune it as they pleased. In general, though, Dalvik's more compact executable format (DEX) makes it better suited to environments where on-board memory is precious as was the case with early Android devices. Its register-based implementation may also provide better compute performance and lower power consumption than Sun's stack-based JVM on the kinds of CPUs that the OS targets.
*Sorry, Larry, no soup for you.

Categories