Skip to content

Memory Management Guide

florianf edited this page Aug 9, 2017 · 2 revisions

LordTylus' Memory Management Guide for RoboVM

I had problems when doing some Video-Frame capture with the AV-Foundation. In worst case my app just crashed with interesting error messages. Or sometimes it just stopped working but kept running.

As I found out, when developing with Obj-c there are two major ways to manage memory. You either do it yourself, or let the AutoReleasePool take care of it.

Doing Memory Management yourself

when doing it yourself you have to work with retain and release to get it done right. I have not done it myself, but I did some research of it. According to the documentation when you call retain on an object you prevent it from being deallocated (so it will not be removed from the memory). Internally there is a counter that keeps track on how many different parts of your program want to keep that Object.

Once you no longer need it you call release on the object. This decreases the counter. Once it reaches 0 the object may get deallocated.

See Documentation: https://developer.apple.com/documentation/objectivec/1418956-nsobject/1571946-retain https://developer.apple.com/documentation/objectivec/1418956-nsobject/1571957-release

Dispose on the other hand appears to be the brutal method to get rid of an object. since it just removed it from the memory. this will normally be called when retain count reaches 0. But you can call it yourself.

https://developer.apple.com/documentation/objectivec/1441571-object_dispose

Working with an AutoReleasePool

The AutoReleasePool keeps track of retain counts by itself. So you dont have to call retain/release or dispose at all. It seems like you also must not do this. More of that later.

As I found out when using Obj-c you just have to call autorelease on a newly created object. That will allow the AutoReleasePool to keep track of that object.

I did some testing and noticed that when working with RoboVM I dont have to call this method at all. I suppose RoboVM adds it automatically. I verified it cleaning up correctly by creating a sample app that just creates some trash in a for-loop. That trash was removed correctly after it was no longer needed. (According to Memory-Profiling with Instruments)

https://developer.apple.com/documentation/objectivec/1418956-nsobject/1571951-autorelease

Problems I had With AutoReleasePool

I had some strange App-Crashes when calling release, or dispose by myself since basically calling release may cause the Object to be deallocated, or in case of calling dispose it deallocates it for sure.

So when working with an AutoReleasePool that calls release on that object once you no longer need it, it may invoke a so called zombie. You speak of zombies once you try to invoke an object that is already deallocated. (There even is a Zombie-Detection function in Instruments you could try and check out)

After I called release on my own and the AutoReleasePool did the same a few lines of code later it may happen that the object already is gone. So It basically is an IOS Internal NullPointerException that causes the App to Crash.

Same happens when you call dispose.

Personally I prefer using the AutoReleasePool since its very similar to the way Java handles Memory. You dont have to do memory management yourself and it just works.

How did I get my App running

After I removed all retain/release and dispose calls that I made for some reason, the app kept running with the AutoReleasePool. But sadly my Video-Frame capture stopped working after a few captured frames. (No crashes just no more new frames to be captured)

I havent figured out why but for some reason calling a System.gc() manually after each frame capture fixes the problem. I am not yet sure but I suppose it has something to do with the frame buffer. Calling Release or anything similar on it made the app crash. But once System.gc() was called it cleaned up everything correctly.

At the moment I just live with it. But I hope it is a bug or something that causes me to clean up memory like that and is not the intended way to do so.

In case you are interested I documented my solutions for Video-Frame capturing and my memory problems here: https://github.com/MobiVM/robovm/issues/146

The Documentation of the given Methods references to: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html#//apple_ref/doc/uid/10000011i

I hope could help a little, but since I am by far no expert on the topic I may have got something wrong myself. So please keep that in mind. Since RoboVM uses a lot of Native IOS functions it really helped me just reading the IOS documentations on different topics so far.

Just reading Obj-c code can be a bit frustrating and needs some time to get used to.

Taken from issue https://github.com/MobiVM/robovm/issues/189

Clone this wiki locally