5 ms·
On Android, Garbage Collection Can Kill You
- lucian1900 14y agoActually, Dalvik's GC just plain sucks, too. Clojure has a similar problem: works fine on desktop JVMs, but even initialising it takes many seconds on Dalvik.
- soc88 14y agoWorks without problems in Scala. Maybe Clojure isn't using the available resources efficiently enough?
- loup-vaillant 14y agoMaybe the Scala examples you think of indulge in quite a bit of destructive updates? Functional programming style tends to generate lots and lots of objects which die very young. Garbage collectors must be tuned for that. At least they should be generational. Mayhaps Dalvik's current GC is not?
- masklinn 14y agoAye, seems Dalvik's GC is a pretty simple mark-and-sweep.
- soc88 14y ago> Functional programming style tends to generate lots and lots of objects which die very young. Well, there is a lot of Scala code out there doing exactly that. HotSpot has no problems with short-lived objects in pretty much all its garbage collectors while Dalvik's GC is just a lot less sophisticated and mature. So I mainly agree with you, but the proposition of Language allows producing lots of short-lived objects + Dalvik sucks ------------ Programs in that language have to be slow doesn't hold in my opinion, as seen in the differences between Scala and Clojure.
- lucian1900 14y agoClojure still generates a lot more garbage, especially during bootstrap. This can be seen easily with VisualVM on the desktop, comparing hello world in the two languages.
- loup-vaillant 14y ago> Well, there is a lot of Scala code out there doing exactly that. I talked about specific examples that I don't even know of. I don't know Scala enough to know whether non-destructive updates are the default. Are they? What about the core libraries? I agree your proposition in fixed width font does not hold. I was merely asserting this one: Program P produces lots of short-lived objects + Dalvik sucks (or is tuned for long lived-objects) ------------------------------------------------- Program P have to be slow
- lucian1900 14y agoScala generates a lot less garbage, by construction. A lot of that has to do with its compilation model, which is a lot closer to Java's than Clojure's is. Clojure just assumes the JVM can deal with it, and desktop ones do just fine, hence why no one noticed.
- vetinari 14y agoYour laptop has 10x memory bandwidth of top-end Android phones (and 20x of midrange phones). Double the numbers for desktop. In short, mobile devices are different than laptops/desktops. If you threat them same, your application will suck.
- ajross 14y agoCloser to 5x than 10x. Don't do the math based on the clock speed, look at the cycle times (which are mostly the same between DDR3 2000 and LPDDR2 533). A desktop or laptop CPU (unless by "laptop" you mean "netbook" -- laptops based on mainstream CPU cores have the same memory interconnect as desktops) will have two 64 bit DRAM channels, a typical phone will have a single 32 bit channel.
- pacaro 14y agoI use completely different threats for mobile devices, laptops, and desktops. If you don't stop misbehaving and start running my code correctly I'll ((forget to take you out of my pants pocket on laundry day)|(see just how far that hinge will bend)|(take you to the landfill)) None of these work BTW. Edit: Sorry
- briancooley 14y agoIt's been a while since I looked at the Clojure source, but from what I recall, the initialization problem is almost wholly related to loading all of clojure.core, not garbage collection. If you're hitting slowdowns after initialization, there's a good chance it's reflection, not garbage collection. Type hinting can help if that is the case. Because of the way that Clojure reuses immutable data structures, it doesn't do as much garbage collection as one might think.
- freehunter 14y agoI guess from the headline, I expected more than what everyone already knows: garbage collection takes up processor time, especially on unoptimized code. I was expecting something new.
- aidenn0 14y agoAh yes, but the article claims that Dalvik has a poor gc.
- fragmede 14y agoOn Google App Engine, Over Quota can kill you: Over Quota This application is temporarily over its serving quota. Please try again later. is all I get right now from the link.
- reginaldo 14y agoCache link: http://webcache.googleusercontent.com/search?sourceid=chrome&ie=UTF-8&q=cache:http%3A%2F%2Fwww.war-worlds.com%2Fblog%2F2012%2F06%2Fon-android-garbage-collection-can-kill-you http://webcache.googleusercontent.com/search?sourceid=chrome...
- astrodust 14y agoIt's ironic that we need to use Google to cache a Google site that's over-quota, right?
- ajross 14y agoFTA: "A quick look at the output from ddms shows I was allocating tens of thousands of Colour, Vector2 and Vector3 objects per image" And this is the fault of the garbage collector? Doing per-primitive ops by allocating heap blocks is a disaster, sorry. No one doing HPC does that. This won't run well anywhere, though obviously a desktop machine is going to give you a lot more freedom before you see frame rate problems.
- kevingadd 14y agoIt's the fault of the garbage collector because the JVM provides no sane alternative (like, say, structs, or packed object arrays...). If there's Only One Way To Do It, that One Way should not cause the garbage collector to fall over and choke. It sounds like the desktop JVM handles it just fine, in comparison.
- ajross 14y agoWhich is one reason that no one does HPC (or related tasks, like image processing) in Java. To be fair: Android has a nifty NDK that works very well for tasks like this.
- soc88 14y agoCould you please tell me in which alternative reality you live in? :-)
- ww520 14y agoWhy not just pre-allocate the objects and reuse them?
- mwd_ 14y agoThis is what I do for Android games -- design things to be mutable and pre-allocate however many I'll need during a level. You also have to avoid foreach because it creates objects. This is an area where C# is better. You can create classes or structs and structs go on the stack. Structs are a lot more appropriate for objects like rects.
- chrisreed212 14y agoIt's not GC per se, it's that the Dalvik JVM doesn't do some analysis and note that the object that you create to pass to a method which doesn't escape it can be created on the stack as it is guaranteed not to exist beyond the calling method.
- cluda01 14y agoYou need to be really careful when using object pooling and carefully consider two things: synchrony and lifecycle issues. Synchrony issues occur when sharing an object pool among multiple threads. If you're sharing an object pool and using an unsafe data structure you will run into concurrent modification exceptions. Another issue could also be that using a thread safe data structure (or more simply a syncrhonized method) will lead to huge performance degradations because it is a central point of contention. A third issue with object pools is that if you have multiple threads using an object pool it might fill up your entire heap with cached objects. The lifecycle issues come into play when you ask the question, "Who returns the object to the pool?" For example you could have 1 thread passing an object to another thread and then returning the object to the pool. If not considered you could run into a possibility where 2 different threads are operating on an object as if they are the sole owners leading to unexpected results.
- stevenwei 14y agoIt's a bit strange to me that one of the recommended optimizations is to create fewer objects in a programming language that is heavily object oriented.
- reeses 14y agoI remember the last time I got involved in one of these discussions, where the same give-and-take was brought up: https://groups.google.com/d/msg/comp.lang.ruby/vWcRBbg8VGE/0OUuQmCMuFcJ https://groups.google.com/d/msg/comp.lang.ruby/vWcRBbg8VGE/0...
- jemfinch 14y agoIs this really a credible complaint? Someone who wrote this: public int hashCode() { return new Double(x).hashCode() ^ new Double(y).hashCode(); } does not seem to have the requisite understanding of how things to work to declare the inferiority of a widely used garbage collector.
- swah 14y agoCan you explain what is obviously wrong in this code?
- deleted 14y ago[deleted]
- jemfinch 14y agoYou don't need to allocate a new double to call hashCode on it. You can just call hashCode on the double you already have. Out of curiosity, what language background are you coming from that this isn't obvious?
- reeses 14y agoYou beat me to this issue. When I read this code I cringed, because it's so naïve it's like reading something intentionally pessimized, such as "if(new String("true").equals(new Boolean(b).toString()){...}" instead of "if(b){...}".