views:

122

answers:

3

When ran in activity monitor, the real memory usage for a program running the following piece of code will increase endlessly:

CGRect frame = CGRectMake(0,0,0,0);
while(true)
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    UIView *test = [[UIView alloc] initWithFrame:frame];
    [test release];
    [pool release];
}

What happens is that all objects derived from UIView will leak. Some will leak more than others (UITextView in particular has drawn atention to this problem). The leaks are not actualy discovered in the leaks monitor - their presence is only revealed by the constant increase in memory usage - which eventualy leads to the app being terminated by the OS because of memory exhaustion.

Has anyone noticed this before? For the record, the code was compiled for OS 3.0.

A: 

It could be that UIKit is using shared singleton objects when constructing UIView and something allocated by those singletons are not necessarily cleaned by NSAutoreleasePool but is cleaned during standard event loop execution via other means.

tequilatango
MihaiD
A: 

I agree this is likely a bug in iPhoneOS. It looks like the CALayer is not getting released. If you force an extra release of the CALayer ([test.layer release], which is an insane thing to do, but "works"), you'll dramatically reduce memory usage, but you'll find that QuartCore is still leaking at least 16 bytes per iteration, which adds up fast in your stress case. I'd open a radar (bugreporter.apple.com).

Rob Napier
+1  A: 

I guess this is an issue with Instruments. Instruments does not work correctly when using with iPhone OS 3.0, e.g. you can't see a stack trace. When using 3.1 in the simulator, this issue disappears (see images). The fact that these do not show up as leaks in Instruments contributes to my assumption.

Of course it could also be that this was indeed an issue with iPhone OS 3.0 and has been fixed in iPhone OS 3.1.

Instruments with OS 3.0
^^ Instruments with OS 3.0

Instruments with OS 3.1
^^ Instruments with OS 3.1

This is the code used (in applicationDidFinishLaunching:)

NSUInteger i = 0;
CGRect frame = CGRectMake(0.f, 0.f, 100.f, 50.f);
while (i < 100000) {
    UIView *test = [[UIView alloc] initWithFrame:frame];
    [test release];
    i++;
}
Pascal