Android’s Dalvik Virtual Machine
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
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.
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?