Why Is Our Monotouch App Breaking in the Garbage Collector? It Is Not Out of Memory

What does it mean if the garbage collector is more aggressive in Monotouch 4?

We found that sometimes developers would run into strange problems like dialogs would sometimes stay on the screen, and sometimes they would vanish without leaving a trace and with no explanation of why this happened.

This typically happened when you created an UIAlertView and kept no references to it, so as far as MonoTouch was concerned, that object was garbage (you did not reference it from your code, so you did not have a use for it).

But whether the dialog vanished from your screen immediately or later depended on whether the Garbage Collector's heuristics had determined that it was time to run a collection. If you had created a dialog just after a collection, chances are, your dialog would stay on the screen. But if you were very close to a collection, or if you had a background process consuming memory, then the GC would be triggered.

This in general was confusing to users, "why are things vanishing randomly". The answer was: if you did not keep a reference to it, the GC assumed you did not care.

To make this more clear to our users, when running MonoTouch on debug mode on the simulator (and there is a command line option to control that for any builds), we added a thread on the simulator that continuously calls GC.Collect() every few seconds. This makes it more obvious that you might have not kept a reference to a dialog of yours.

Later on, we found out that a very useful and common pattern was to keep two kinds of dialog boxes around that really have no use other than their side effects: UIAlertView and UIActionSheet. We altered MonoTouch so that it internally keeps references to those two until dismissed.

So we ended up with the best of both worlds: during the development cycle you catch earlier missing references to objects that you need, and we took care of the two most common cases that are only useful for their side effects.

Monotouch Memory Profiler: what does the number total memory stand for?

Total memory is the amount of memory used by all the managed objects. The profiler just adds up the memory used by each object.

This is not the total amount of memory used in the process, for a couple of reasons:

  • MonoTouch doesn't allocate memory on a per-object basis. MonoTouch allocates memory in chunks instead, and when a new object is created, it will usually be allotted memory already allocated. In any case this is usually a difference you can ignore between the total memory the profiler reports and the real amount of memory your app uses (and it is not the reason for the difference between 5MB of managed memory used and the 30MB Instruments reports).

  • MonoTouch (and therefore its profiler) does not know about any memory allocated by native code. If you for instance create an UIImage, the image data is kept entirely in native code, and it won't show up in our profiler (you will see UIImage instances in the profiler, but the memory used by each will be the managed memory used, which doesn't include the image data). Another example is if you load a view from a xib: if you don't access the tree of objects from managed code somehow, no managed objects will be created for any of the objects in the tree, and nothing will show up in the managed profiler. This is the real difference between the 5MB from the managed profiler and the 30MB Instruments reports.

Also have in mind that MonoTouch itself will use more memory in the simulator than on device, since on the simulator it's been tuned to compile fast (to make debugging as fast as possible), while on device it's tuned for better runtime performance.

Better MonoTouch crashes with TestFlight

I'm not familiar with MonoTouch, but what about using the Remote Logging features of the TestFlight SDK?

Is there an official reference stating that battery life is one of the reasons why a Garbage Collector was not included inside iOS?

... stating that battery life is one of the reasons why a Garbage Collector was not included inside iOS?

  • I would call that either good PR or agressive fanboyism. A good GC adds little overhead, especially no amount of overhead anyone would have to be concerned about. Problem is that Apple doesn't have a good garbage collector.

  • Objective-C's garbage collector is conservative and doesn't do compaction, which means that applications will leak memory over time and if you have a long-running app on your phone it will eventually eat up all available memory and crash. Actually that's the reason Apple recommends not using it for long-running tasks even on Mac OS X.



Related Topics



Leave a reply



Submit