Google I/O 2008 - Dalvik Virtual Machine Internals

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone welcome back to Google i/o I hope you had a good time yesterday I hope you have a good day today I'm Dan Bornstein I'm here to tell you about the dalvik virtual machine so a little bit about my background I joined Google in 2005 to work on the Android project and I've been working on dalvik almost the entire time before Google I worked on a couple different VMs at a few different companies including on the hip top virtual machine immediately prior to Google and although I did start the dalvik project at Google the virtual machine and the libraries wouldn't be where they are today without the work of a whole lot of other people about half a dozen core contributors and a slew of other supervisor helped throughout the team so thanks to those guys if you're curious about the name dalvik Iceland is in the northern part of the country northern part of Iceland it's if you want to go to the Arctic Circle you can catch a ferry there okay if if you're familiar with Android at all you've probably seen this diagram very briefly Android is a new platform for mobile devices and it really is the complete stack includes layers from the OS kernel at the bottom and drivers up through an application framework at the top and it even includes a few applications you write your you write your applications in the Java programming language and they get translated after compilation into a form that that runs on the dalvik virtual machine and the rest of this talk is really just about the virtual machine I'm going to give you a couple a tour of a couple aspects of the VMs design and in particular how it was influenced by the constraints imposed by the rest of the platform and at the end I'm going to just a couple pieces of advice for your application development on on this platform I'm going to assume you're generally familiar with the java programming language and know at least a little bit about what it means to be a virtual machine and if I if I omit a few details I'm going to try to leave plenty of time for Q&A at the end so just be aware of that and it just hold your questions and I will try to answer anything you have after the talk so the the virtual machine again is is designed based on the constraints of the platform and you can see a few of the the key ones we're assuming not not a particularly powerful CPU not very much RAM especially by say today's desktop standards an easy way to think about it is as approximately equivalent to like a late 90s desktop machine with a little more modern operating system but with one very important constraint so battery batteries are getting better as time goes on just like any technology unfortunately it doesn't look like it's keeping up with Moore's law so you know 18 months your your CPUs are getting faster your your memory density is getting you know twice twice as much but your battery life isn't quite keeping up so that really that really is a key concern for any kind of mobile development so now you know a little bit about our constraints let's see how we address a couple of them as I said we're expecting to run on fairly low memory devices by desktop standards so in particular this is this is kind of how a low a low-end Android device is going to look in terms of system characteristics so you know once once everything is started up on the system we're not really expecting there to be that much memory left for applications and of course so we try to to make the most of that but one wrinkle in the works is that are the Android platform security relies on modern process separation so each application is running in a separate process there's a separate address space it has separate memory and apps are not allowed to to interfere with each other at at that level and and so that that means if unless you do something special that 20 Meg's really isn't going to go go far at all and in a differences a modern platform that we try to make it you know have a rich have a rich set of API for developers to use we have a fairly large system library and so again if you don't do anything special well with a 10 Meg library 20 Meg's left for apps that really really doesn't leave much space at all and I think I've had a previous slide that we don't have swap space so just want to emphasize that so there's no if you have 64 Meg's of RAM you have 64 Meg's of RAM and that's that's kind of the the size of it okay so as I said we translate job Java dot class files into a new form to execute on the device that form is called a Dex file it stands for dalvik executable and here is in a very general way what what a Dex file looks like the sizes of those areas aren't to scale but it's meant to give you at least a general impression after the header there's there are these five separate constant pool sections each constant pool section is of a particular type you can see what they are there and just for example the top there the string IDs section identifies literally strings so any string that you have in your file be it a in your in your code either an explicit quoted string in the source or say the name of a method name of a field those will all end up having references in the string ID section and then towards the bottom there are series of class definitions so a dex file contains more multiple classes each one of those has a little a little section there and then at the bottom there's general data so all of these other sections are going to are pointing will end up pointing at that data and actually the sections will point back and forth at each other so for example a type ID so this is something that names a type such as a class or a primitive type well that the name of that is represented in the strings a method has a name and a signature and you can see how those point around they said there's a there's a a build time tool that does this translation so this is just a simple illustration of how say several classes in a jar file turn into a single Dex file okay and this is just just a few classes I'm going to use as as an example so there's a interface and implementer of that interface and use of that of that implemented interface here is approximately what that looks like as separate class files this is a very oversimplified diagram but it again it's it's meant to give you a flavor of the of the strings in that in those files and the the various references and you can see that there's a fair amount of duplication what I'm pointing out here are the method signatures so each one of these classes refers to a method which takes the same arguments in the same return type and so each one of those classes is going to have that that full signature there and in addition there's a fair amount of strings that label internal bits of the class files themselves on the other hand this is what it looks like as a Dex file again we we've collapsed all of those the separate constant polls into one constant pool and as a result there's there's a bit more pointing around inside a Dex file but as a result we get to share a lot more so you can see that there's there are many fewer boxes in this diagram than there were in the in the previous one and that really does represent that there's there's less total storage required for this shared constant pool in a Dex so the point here again is that sharing these separately type constant pools among all the classes it's reducing the amount of data that you need to represent all of them together and in addition to this this sharing just at the constant pool level we were fairly careful about how we lay out all of the structures in the file and I'm not going to talk about that more but I'd be happy to answer questions later about that but I wanted to just show you kind of the high level conclusion so these numbers are sizes in bytes of the system libraries of the Android platform and along with a couple of sample applications I took these numbers about two weeks ago so they're reasonably accurate so what you can see there is that a normal jar file is generally about half the size of the uncompressed class files and at the same time the uncompressed Dex file that represents the exact same code is at usually a couple percentage points even smaller than that compressed jar file and you may be wondering why we care so much about having these good uncompressed characteristics well so here's why so on really any modern operating system you can think of there's being four different kinds of memory in a in a very general sense and that's two variants along to act on sort of two axes there's clean memory versus dirty memory and there's shared memory vs. private memory clean memory is simply any memory that the operating system kernel can drop from from main memory and not have any impact on the kind of the overall semantics of the system and the reason it can drop it is either because it is say just a page full of zeros and the kernel knows that oh if it's zeros I can recreate a page of zeros on demand and similarly if it's backed by a file you can you can map in those pages from the file again as you need to undemanding memory is simply memory that is used only by one process and shared memories memory that's used by multiple processes as if a clean memory is - is ideal because the kernel can just eject those pages from RAM pretty much it will and share it is better because any cost of that memory that is going to have to stay in main main memory until it gets freed that that cost is at least amortized across multiple processes so shared shared clean is even even better than them private clean but but either kind of clean memory is good private dirty is--look is the kind of memory that we want to minimize so on the android platform this is kind of how it shakes up as as clean memory these these uncompressed Dex files get mapped in and these are either the the system library obviously and also any any application Dex file these all get to get to be mapped into memory and private dirty memory is any of the the associated structures once you start up the virtual machine when you load when you load a class when you refer to methods these require some amount of life of live dirty memory to represent as well as the general application heap when you construct objects they have to go into memory and that that becomes dirty memory in for for any given application it's going to have some Co generally going to have some code that is private to it it's going to have its own heap so these are going to be private memory a private private dirty memory and the important question is what can we do to have shared dirty memory and our solution to that is this thing that we call the zygote what we do with the zygote as its name implies it it comes into existence fairly early on during the boot of an android system and its job is to load up those classes that we believe will be used across many applications so it goes and creates its it goes and creates a heap it goes and creates that dirty memory for all to represent those classes and methods and then it sort of sits it sits on a socket and it waits for commands and when it gets a command to start up a new application it it does a normal unix fork and then that child process becomes that target application and the result of that is this so the zygote again has made has made this this heap of objects it's made this live dec structures and then each application that then then starts up instead of having its own memory for those things it just shares it with the zygote and also with any other app that's also on the system so back to that that slide answer this answers the question so our goal again is to get as much as much memory to be mapped clean as possible but we at least have have this out for where we really do have to allocate that we can reduce the cost in terms of the the whole system performance so garbage collection actually throws a little bit of wrink of a wrinkle into things in in general and there are two strategies for how one represents the meta information that you need when doing a garbage collection a garbage collection on the left you can see one one style is you have this associate information st. mark bits sitting next to each object that's allocated so that when you when you do a garbage collection that data is is right there so if you're going to scan an object you'll have the say the mark bits right right they're ready to go on the other hand you can keep all the object the the kind of the live object data together and have this separate allocation for your garbage collection information and the argument can really go either way and at least in the larger sense for like I'm on the one hand if you are if you have the the mark bits embedded with the object well that means that when you're garbage collecting those the the cache lines for that object will will already be warm by the time you need to scan the object on the other hand you have better when you're not garbage collecting if you keep the if you keep the garbage collection information separately when you're not collecting then you have a more dense cache so that's that's the big picture however again with with the Android platform we we do have we do always have to keep in mind that we are trying to exist in a world where there are these multiple processes all living on a fairly constrained device and you know they are separate processes each process has a separate heap each heap is garbage collected independently and that really led us to the conclusion that for Android at least having separate having the separate garbage collection information having having markup it to be separate is the only viable solution and this is particularly true because of that because of that zygote process remember the zygote has its own heap and that that heap is shared so if we had mark bits interspersed in that so I got heap the moment that we did a garbage collect the process would try to touch those those pages in the zygote and therefore force them to be unshared so we would very quickly find that instead of having shared dirty memory we would have private dirty memory and that would kill kill the memory performance on the system and I should add one one additional benefit is because most processes aren't garbage collecting most of the time we don't actually have to allocate that that mark array except during those moments when we're doing the garbage collect and again that means that there's that much more memory for additional apps to be running simultaneously ok now I just want to take a few minutes to tell you what we do on the CPU front again as I said at the beginning we're running on a platform or expecting to run on a platform that that looks like what you might have had on your desktop ten years ago and you know you can you can see that it's a fairly slow bus almost no data cache at all and I just want to re-emphasize that there's very little RAM for an app for applications once you consider all of the things that your device is doing say as a phone it has to answer phone calls it has to be able to take taken send SMS all of these things are essential services as far as the user is concerned so before I tell you what we are doing to address these I'm going to tell you one thing that we're not doing at least in the one dato timeframe so we're not doing a just-in-time compiler and the reason we don't is it gets right back to that memory issue when you when you compile code from from set from a byte codes to assembly that's typically going to make the code grow at least a bit if unless you're unless you're doing something fairly clever you're not going to be you're you won't be you you'll be using you'll be using dirty memory for that for that JIT cache so that again increases the memory pressure and in addition if you look at the the big picture of the system we're we're providing a lot of of native code to do the really heavy lifting so to do the the 2d and the 3d graphics to do audio and video so we provide native libraries for all of those things so it so the interpreter performance or the the the the high level language performance really doesn't come into play for at least a large class of things that that you'll be doing a lot of the time and if you're if you're a platform developer as opposed to an app developer you can always add new functionality that you need via via j'ni so the short version really is is you can you can always imagine an application that you would want to write that could could use just a little bit more CPU efficiency however you could you can there there plenty of apps that there that will do just fine and generally just with a little careful coding you can you can really mitigate any any negative effects that there otherwise would have been and I'll talk a little bit about that later so what what are we doing to actually be efficient on the platform so first of all when an application gets installed and also when the system itself gets installed the the platform will the system will do a lot of work upfront to avoid doing work at runtime so one of the major things we do is verification of Dex files and what this means is that as a as a type safe reference safe runtime we want to ensure that the code that we're running doesn't violate the constraints of of the system doesn't violate type safety doesn't does it doesn't violate reference safety and for Android this is really more about minimizing the app the the impact of bugs in an application as opposed to being a security consideration in and of itself again this is because for Android the platform security is really being guarded by the process boundaries as opposed to anything that we're doing within a single process although this is at least a little bit of a concern in for our more sensitive say system processes where we where we really want to try to guard against bugs because those bugs could turn into security violations in addition to verification we do we do optimization and so the first time that that a dex file lands on a device we we do that verification work we also we also augment that file if we have to we will do byte swapping and pads pad out structures and in addition we we have a bunch of other things that we do such that when when it comes time to run we can run that much faster so as an example of static linking what before when a dex file arrives on a device it will have symbolic references to methods and fields but afterwards it might just be a simple simple integer v table offset so that when for for invoking a method instead it instead of having to do say a string based lookup it can just simply index into a V table and just as another example you are probably aware that the the constructor for java.lang object has has nothing does nothing inside it and the system can tell so instead of instead of actually doing that anytime you're constructing an object we know to avoid just making that column at that actually does make a significant performance impact the most radical thing that we do index files is to have an entirely new bytecode instruction set Dex bytecode is defined in terms of an infinite register machine with no intra-frame stack so there's there's a normal machine stack in terms of one method calling another but with within a method it's all just registers and we we chose this because it it lets us have a very efficient interpreter because each instruction that we interpret is semantically more dense and I'll show an example of that in a couple slides so here's a couple statistics this is the just a general general expectation what you get what you can find when you're converting a set of dot class files into a Dex file we have we have fewer instructions and we have fewer code units and I'll talk about that in a second but we do have we do have more bytes and the the distinction here is that a code unit in in a dot class file is a single byte and a code unit index is is two bytes and in the interpreter itself we can we can shoe reads to read those pairs of bytes at a time and so that helps mitigate the the impact of having more bytes typically and I'm just going to go walk through a couple of actual examples these are all real I used the the real tools on our device to to compile these and dump the results so no no hand waving at least for the next few slides so this is just a short but I hope realistic method so that we can compare the the various bytecode and it is simply adding adding up the contents of an array and returning that value so this is what it looks like as a dot class file or the the bytecode of a dot class file and I've highlighted the loop in red and I've annotated it so that you can see what each instruction is doing in terms of reading or writing a local variable or or a stack location and you can see the summary stats up up at the top right those say those 45 reads are really 25 byte byte reads to read those instructions in 12 reads of the stack eight reads of the local so that that's all 45 similarly you can you can break down the writes and this is I should say that those stats are for effectively a naive interpreter and you can say but you can save a bit if you if you're a little more clever you can probably save it at least 6 6 reads at least 6 writes with a with a fancier interpreter but that gives you a general picture here's what it looks like as a Dex file so you can see there's many fewer bytes many fewer instruction dispatches less than half the number of reads and writes and I should add instruction dispatch is one of the big killers of interpreter performance so it really helps to be able to - dispatch fewer opcodes in your especially in your inner loops okay so sometimes you really need to have just a big array of data and if you've ever looked at what something like this looks like in a dot class file it's not pretty so that this really is the code that it's needed to initialize that previous array it's 44 bytes of instructions another 35 bytes in the constant pool and again it's for instruction dispatches just to initialize each element and each time you add another element to say in inter a it's 11 bytes of coding constant combined and another for instruction dispatches so a lot of people are aware of this particular problem and there's a standard workaround for that so here you can see that what we're what we're doing is representing that int data instead as a string because strings are a little more compactly represented in a dot class file unfortunately this still has a couple of problems one is that in order to decode that string you have to you have to have a bit of code in a loop and it's going to end up doing even more work than the original version that I showed and in addition that string is represented less than ideally in a in a class file because it's encoded as utf-8 each each one of those each one of those those characters really will turn into three bytes so you still have some expansion compared to your original data so knowing that this is what we do in a Dex file this is the same code term which has been translated Dex file you can see that for in this case we're really we're only using 46 bytes for for this example and as you add elements to that inter a it's just four more bytes per element which is exactly the data represented and we only have to interpret one opcode to do that entire initialization and that's the third one down the filler array data as I said if we wanted to add say six more elements it's really just adding the six more elements worth of data and this is both a speed and a space efficiency win measured on our system libraries it saves us something like 100k oh and just want to mention if you look at at number nine there the no op we do that so that the the array data itself is aligned on an INT bandar-e and that makes the reading that data a little more efficient in the interpreter I asked that question during during Q&A I'll get to it okay I'm going to give you a very brief introduction to how bytecode interpreters are put together this is just a toy interpreter I will give you exactly one guess about the output of this program you can imagine that instead of consuming characters from from a string each one of those characters could be a complex opcode with a non-trivial implementation and this is a perfectly reasonable way to put together an interpreter if performance is not a consideration and the the - the big problem with this is there's a lot of excess branching so with that outer for loop at the end of each opcode you're branching back from the bottom of the loop back to the top within each opcode at the end of at the end of it you're branching to the bottom again at the at the top at the top of the loop you're branching into an opcode there's so something like four branches just to do one opcode so the fine folks who put together the GCC compiler or very aware of this problem and there's a great extension to the length to the C language that helps with it and it's called computed go-to so this is one case where go-to really isn't evil so in this case instead of having that having an explicit loop and an explicit switch statement we build in that switch into the into each opcode so that when you're done interpreting one opcode you you immediately can load up the next opcode and branch to it directly so just one branch per opcode so here's where this toy example will break down a little bit but suffice it to say that there's still cases where a human can do better than a compiler at things like register allocation and laying out laying out some data structures so it's possible to write effectively the same technique as that as that last last one in assembly so here you can see I've alighted a lot of the details but but the dispatcher I've written I've fully written out you can see there's still two two reads of memory to do that dispatch the first read is reading from your interpreted program counter and the second read is reading from your opcode table to find the address of that next opcode so as I've implied before at least any memory activity that you have is is going to be a significant performance impact so if you can get rid of a read you're you're doing pretty good and that's exactly what we do so instead of having that second memory read what we do is have the base address of the entire interpreter sitting in a register and we guarantee that each opcode takes up the exact same number of bytes so we'll add it if it if an opcode happens to be short there are a few of those we won't we won't use the the entire space allocated for that opcode and similarly or if a opcode happens to be one of the the more heavier-weight ones such as a method invocation or field access stuff like that we will branch off to a helper function but what that what that means so there's there's really two benefits here one is again we're avoiding that dispatch and another one is that we get to align the implementation of each opcode on on a cache line boundary so if there's an if there is an in an opcode which doesn't happen to be used a lot it won't be taking up any space in the cache and that helps that helps with the with the leaving space for for any other data accesses that that your code might want to do so now that you know a little bit more about how the VM is put together I just want to take a couple minutes to talk about how you can optimize your code for for Java or really for mobile devices in general again the really big difference is the battery so if you do if you do anything I mean if your code does anything this means that your code is consuming milliwatts and those milliwatts have to come from somewhere that somewhere is the battery again battery technology keeps getting better but if it's not plugged into the wall it's going to it's going to run out eventually so I tend to think of the optimization problem in terms of the terms of timescales so there's really there's human human time scale versus computer time scale on the human side there's human interaction is say a fast typist who can type at let's say 10 characters per second or so if you're dragging a mouse or doing a finger gesture it's a 15 to 30 points per second is really about what you need to register on the perception on the perception scale that's more like if you're listening to audio or watching video you'll have to have say 25 to 30 frames per second and you'll want continuous audio that's that's reasonably synchronized at the computer scale this is when when you're doing some computation and you're just computing all out and it doesn't matter what what the what the user is interested in the computers needs to to crank through and the optimization problem is is really a matter of trying to avoid having to do computer scale computations so you know at computer scale that's when you're really eating through them eating through the battery and if you're if your code really has to has to run a computer scale any optimization that you do that doesn't sort of bring you up to one of the other scales is really it's sort of prolonging the agony before death so with that my my first advice for well-behaved applications is to get plenty of rest so a good app is one that that's sitting and patiently waiting for for user input for network input and when that input comes in it looks at that input it reacts to it and it just goes back to sleep so so for example you know as you're typing on the on a keyboard you get that key input and you want to react to it you want to you know display the next that display that character move the cursor forward and then again go back to sleep and help that cursor that's just an animation and so it should be sleeping say for a half a second redrawing the next one sleeping a half a second again you add it up hopefully your you end up sleeping most of the time and that helps prolong your battery life but sometimes you do have to have a loop and sometimes it really does have to operate at least briefly on computer scale and so with that my advice is to loop wisely this is just seven typical headers of a four loop I've arranged them approximately in in order from most efficient to least efficient and just I should just add as a caveat in really unless you're operating a computer scale this this this advise doesn't matter so the first three of those are all about in the same territory of efficiency but the first one you can say is seeing was a little unnatural at least in many circumstances so I wouldn't go crazy sort of making all your loops countdown unless it really makes sense for the code so I would really advise if you can manage to fit your fit your loop into one of those two then you're doing you're doing pretty good however if you find that you have to do a lot of generic object based iterators at computer scale then you have a problem and the it's generally a solvable problem but just be aware that if you find yourself doing that that you should probably try to find a different way to help give your give your user a little more battery so especially because doing like making an iterator it's going to do an object allocation and if you keep on allocating objects at computer scale that means you're garbage collecting a computer scale and GCS although although art aren't too bad if you do enough of them that they are going to impact your performance and that really gets to my last piece of advice which is just avoid allocation and on the one hand if you have short-lived objects so you know for example those iterators probably aren't each each one it aren't isn't going to last too long but they do need to get garbage collected and garbage collected garbage collection takes CPU time takes energy and on the other hand if you have a long-lived object well that's dirty memory and your user wants to do something else with that it's you know they want to be able to run every app under the Sun simultaneously and the more long long-lived allocation you have the fewer apps that your that the user is actually going to be able to run I know this is a little bit of a bind I'm saying don't allocate short don't allocate long really it boils down to to be frugal in how you allocate if you're allocating a a a long-lived object make sure that that allocation is in support of operate one of the human time scales as opposed to operating at one of the computer time scales so that's the extent of my advice for you and that's about all I have to tell you today oh thanks they said the design was really a result of these system pressures and we've done we've done what we can to help minimize the pain for developers but of course we can we can only go so far so I hope that that with this knowledge you can you can go and write even better applications for the platform and give the users batteries a little bit of a break so with that I think we have a few minutes for questions and I'd be happy to take them oh and before we get started I believe that you all have little cards for speaker evaluations all of us would appreciate it if you if you would take a couple minutes to fill those out and tell us what we got right and what we got wrong okay sir so you'll mention that the virtual machine was designed to be run on the 64 megabytes does that mean that every single one exceeds 64 megabytes so we that 64 megabyte number is really it's a it's a design consideration for the software development work so as a software developer on the Android project my job is to put together this software I mean I don't put together the hardware and from project perspective we hope there to be a lot of pieces of hardware that that run the Android platform what we wanted to do was define kind of what the low end of what we expected to be able to run on as opposed to saying it must be 64 Meg's we're just saying we don't we don't expect to run with fewer than 64 Meg's if you have if you have more than that we are happy to - you know to have have that extra memory - again run run more applications and you know or eventually say you know augment the system libraries with even more functionality I'm sure and four on yesterday's session that somebody mentioned that there is a low memory killer in the kernel mhm so how does it work with these the dalvik virtual machine so the the low memory killer is this is a part of this is part of the larger system design of Android I'm no expert on it but I can I can talk about it a little bit at least as I said we're you know we want to be able to run as many applications as the user wants to run and the the aim of the platform is to give the user the impression that all apps are always running so if they switch to email their email should just show up if they switch to Maps say the maps should just show up under the covers however if you know loading up the the email application means that there's not enough memory in in not enough not enough application memory to support all the simultaneous uses the the low memory killer will find the application that was used least recently and kill it to make more memory make make more memory available for the the processes that are actually active on the system okay so the the bottom line is that we can have more hardware memory I'm sorry say again so we can provide as many apps hardware memory as possible but the low memory killer won't matter how the virtual machine work yeah the low memory killer really is it's it doesn't it it's it operates at the the process level so the low memory killer can kill a virtual machine just as easily as it could kill a you know of program written in C or C++ I have a question about your for loop example um so once so certainly using the iterator is a bad thing just because of object creation and stuff like that but is it is it really an issue in terms of the garbage collector like are those things are all objects always allocated on the heap or are simple examples like that going to be on the stack no actually we do all allocation for for the for the one over jin' all all allocations are done on the heat okay and so you say new something-or-other work code does it sort of under the covers for you that really turns into a little piece of code on the heat are there any plans to change that in the future or is it not a big deal in most cases or so um I think the the very general answer is we always want to make it better okay um offhand I don't know whether doing a doing stack allocation of of that that kind of object will turn into a net win for the platform very very well might we're we're actually just on the cusp of exploring what we want to do after after 100k Thanks over here so you had a lot of examples of converting class files to Dex files and converting Java to class to Java bytecode to Dex um is there any reason that you started with Java rather than say the common length or the CLR or even writing a new compiler that goes directly from some language to next yeah um actually I think I can answer the second ones with a more definitive answer if you look at the the big ecology of computer systems there's there's a lot of support for the Java programming language so there's you know there's eclipse there's NetBeans there's IntelliJ you know there's eMac support even there's there's jdb there's Jase I happen to be fond of this debugger called Jase Watt and there's there's a lot of activity in terms of of Java development especially in the open source world and when we were building this platform we really didn't want to throw something totally new out there that was Thoth was unfamiliar and didn't have rich tool support and sort of we surveyed things and it seemed like the the local maximum really was supporting programming in the java programming language and and again supporting the supporting the debugger is the IDE s and all that in terms of CLR in particular versus Java I'll have to say my impression is that that there's there's more open source activity in the Java world I don't know if that's strictly true or not but it did seem like a reasonable choice and I guess there was one less he said compile some language say directly into a some other language directly into the the Dex format yes um you know eventually that could happen there's there's nothing that should should keep anyone from being able to to do that however there's you know there were already reasonable compilers for the programming language that we cared about in fact there are multiple compilers and and we will work with with pretty much any of them and in addition there there are other source languages that compile to dot class files and we can already take advantage of or rather the platform can already execute those by virtue of the translation from dot class files whereas if we wrote a source compiler we would only have that one source language okay thank you we're kind of my question so what kind of Linux kernel are you running and what modifications have you made for your environment okay um I'm far from the best person to answer this we are on currently on the linux to six series I don't remember which minor version we're on 24 someone says okay see we have we've actually published all of our modifications so with the first SDK release we also published a git repository you I'm sure you can find it trying to URL for it it's you know and we I believe we push made push regular updates to it so the improvements you mentioned alluded to to the the class files index any improvements that you can actually push back to to the the bytecode Java bytecode or or some some tweaks that you found you can actually push back to the Java world um well the the dot class format is fairly well set in stone so I don't know that there's much say direct influence that our work can have on the dot class format however the just as with with the vast majority of the Android source code all of this is going to get open sourced and my my hope is that this code while it may not say you know trance transfer into some other project directly at least you know the ideas that we've explored can help inform other other projects on you know their their decisions for how they they build similar systems yeah for example just building a better just j2me like a better ball mobile version of java something of that I mean and the second question is it goes along the lines of previously you can actually John - and so um I don't know about JSON in particular there's one major thing that we don't support in the current incarnation at least not not directly because our executable format isn't isn't dot class files once you're on a device there's nothing to read a dot class file so I believe J thon will generate new class files on the fly we don't currently have a mechanism for reading those class files in and translating them on the fly into Dex files so any any language runtime that requires that isn't going to be able to operate on on a Dalek VM without having some major surgery done to it yeah I think when you create an activity or activity they make a little bit of a difference there in the SDK I think when we'll translate to a fork and the other one will translate to a V fork or how to actually work inter internally when you start sub activity as opposed to file activity um like the site goes for example you say that it will start the home screen of right so we'll start our activity very much right so the cycle fork the home apk so the it's not so much say fork versus v fork it's really whether whether you're within the same process or within a different process and each I should caveat I'm also not the best person to answer this question about I'll try to try to give it a go each intent that the the system that the system receives it will try to figure out which which apk is the best best one to deal with it if that if if the if the kind of the application behind that hasn't yet been started then the act of responding to that intent will cause a new process to come into existence yeah okay finally like on Java basically when you implement I've got a VM basically like do you have a lot of naked native codes that you're currently executing on the phone some of those native girls have are blocked a blocking calls and able to say one of those calls blocks and the phone fails the device pretty much then you have like a watchdog timer reset or something of thing like that how the dalvik VM or what do we need to do to get those not a blocking call or or do we need to implement some sort of timer task before we actually make the the native call or how will that work yeah um you you don't generally have to worry about quite that that level of detail of the the way I would put it is that you want your user interface to be fairly responsive so if you're going to do a do a blocking operation especially one that that's going to really block for say four seconds you don't want to do that in your your UI thread you much rather do that say in a side thread right but we're saying is like a OS I mean the VM will be executing actually the native goal so the time of slides will belong to the native right so independently of why you have thread thread wise on on the VM it just doesn't matter because you're actually securing a native call so the the native call is from from the system perspective whether a call happens to be native or interpreted really doesn't make that much difference it's it really does it's really more about what what thread is is doing that and in sort of which and which applications are being particularly active so I think I thought your original question had to do about like not wanting to lock up lock up the system is that right exactly because when you're implemented on Java that's a job am you you should have run into that specific problem so so for us the this may be a little a little oversimplified but our our aim really is that if a process is misbehave it's it's really sort of limited to just that process having trouble and not affecting the rest of the system so for example there are we define there to be say like physical buttons that aren't intercepted by there aren't intercepted by the application so the easy example of that is like the the send like the sender the end button the the home button so if you happen to be as a user you see this application it's misbehaving you should be able to like just hit the HOME key and that app may continue to misbehave in the background but then your home screen will come back up you can do do other stuff and eventually if it turns into a kind of system problem that system process killer can can go ahead and kill it so basically we'll just triggered an interrupt and that's actually hooked to the dalvik VM and it will yeah it's even it's actually hooked even lower lower level than the VM itself yeah that goes yeah okay thanks hmm okay I think I have time for one more question okay good this is a long one oh no I was recently working on an example that needed to perform some image manipulation and it had a had two nested do loops you know going from 1 to 100 one 200 and just a really simple piece of math in the middle I noticed that I could tell it was running depending on how it was 100 or 200 might take a second or so which was kind of long first part is how would i optimize that in in java so it run fast on java then second part is let's say there was a J and I call to do that have you done anything with optimizing the AMI j and i calls to just speed them up over straight j and i well um actually i think i only have time to answer half of that eyes I'm going to I'll answer the j'ni question so we haven't we support real J and I and what we have done is a couple of tweaks to how we implement that to to make it about as painless at painless and efficient as a Jana Jana I call could possibly be so in terms of application level code that's about that's about all we can do in terms of the platform code if you're a platform developer as opposed to an application developer there there is a a way to do a native call that that avoids a lot of the j'ni overhead however for the sake of portability we we only expose that as kind of like a low very low level platform feature so with that thank you very very much for coming and if you are interested in asking further questions I will be at the Android booth out in the hall
Info
Channel: Google Developers
Views: 181,124
Rating: 4.8983426 out of 5
Keywords: Google, I/O, IO2008, Android, Dalvik, Virtual, Machine, gcvio052008, plid6D9B701069B4F2F4
Id: ptjedOZEXPM
Channel Id: undefined
Length: 61min 33sec (3693 seconds)
Published: Tue Jun 03 2008
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.