Android’s Dalvik Virtual Machine

I recently wrote a paper on Android’s Dalvik virtual machine. I’m relatively new to the mobile development space and I was intrigued by some the design decisions that were made. Why couldn’t Android run on the Java platform as opposed to being “Java source code that compiles to the Dalvik executable format.” The JVM as a platform has become something much bigger than Java the language. So why has Google been investing enormously in technologies based on Java the language while building alternative deployment platforms to the JVM (GWT to JavaScript, Google App Engine, and now Dalvik)?Sun had invested enormous amounts of money and energy in the JVM (hopefully Oracle will continue and I can’t see why they wouldn’t especially since they own two of the main JVM implementations), so why start from scratch. Since my knowledge of mobile architectures was, and really still is, somewhat limited, I thought digging into the Dalvik architecture would help shed some light on this question. There is a huge amount information available on the JVM, but there is very little available on the Dalvik VM.  That is to be expected since it is a relatively new platform under rapid development. Given that, I thought I would post the paper as a source for others looking for more information on the subject. You can find it here. Please let me know if you find any errors or problems.

I had originally intended to outline the design constraints, dive into the main architecture decisions, and finish off with some thoughts on the consequences of using Dalvik instead of the JVM and what the Dalvik VM will mean to the developer. I never got to the last section. But I did very briefly cover each of the following topics:

  • Design constraints
  • The Dex file format
  • The Zygote VM process
  • The Register-based architecture
  • Security

One specific omission, both from the paper and the pre-Android 2.2 platform, is JIT compilation. I didn’t cover it at the time because some semblance of the new JIT compiler was already checked into source code and Myriads’ Dalvik Turbo had been announced shortly before. Since a JIT compiler was most likely imminent, there was no reason to talk about why it wasn’t there.  Also there was no information available on the JIT, so there wasn’t much I could say about its design or implementation. For an overview of the new Dalvik JIT straight from the Dalvik creator, Dan Bornstein, see this article on the Android Developers Blog.

Another interesting design decision that I didn’t know about at the time is related to the Dex file format. Dalvik has a limit of 65536 method references per dex file. That is something that I wouldn’t have given much consideration to since it seems like a huge number and mobile apps are relatively small. All code you are deploying with an application does go into the same dex file though. Apparently it is an issue as developers working on both Scala and JRuby support for Android have encountered it. Maybe the bigger issue may be the lack of for a shared library mechanism similar to what you have on the JVM so that you don’t have to deploy the same dependencies in every single application (this really wouldn’t solve the method reference limit problem but would help overall resource usage). I do suppose that you could deploy the shared code in an application and bind to it from your application using a remote service. But as I write this and actually think about it, that seems totally out of the question for something like the JRuby standard libraries.

That provides a good transition into some thoughts on how the developer may be impacted by Dalviks incompatibilities with JVM. I’m curious to hear about what others think or have found. Here is a brief list of some areas that I thought of.

Runtime bytecode generation

Application developers aren’t likely to be doing any runtime bytecode generation in their code but many of the frameworks and APIs that they are accustom to using often do. Dependency injection containers such as  Google Guice is one such example.  I would have to spend some time thinking about how to best use these containers in Android’s activity and service framework but it seems viable. AOP is another area that would be affected. For AspectJ, compile-time weaving would obviously work but runtime weaving is out. (see here for a version of Guice without AOP that should work on Android).  I believe Spring’s AOP is completely proxy based and therefore wouldn’t be affected.  I don’t know about the other AOP frameworks.

Support for non-Java languages

Both the lack of dynamic bytecode generation and the limit on method reference in dex files are two of the the issues affecting alternative languages on Dalvik. Charles Nutter has a number of interesting posts on his work with JRuby.  One particularly relevant is on Precompiling Ruby for Android. There are current projects for making JRuby, Groovy, and Scala first class languages for the platform. I’m assuming there are additional projects for other languages.

Classloading

I think there are some restrictions on or at least differences in classloading but I’m not positive on this.

Support for new JVM features

The invokedynamic bytecode could be one example of this. Will Dalvik support this and others in the future, especially since it is mainly targeted at dynamic languages and not Java?

Are there any other areas where developers may be affected? What are your thoughts on those listed above?


37 Responses to “Android’s Dalvik Virtual Machine”

Leave a Reply