Xcode Zombies - Huge memory leaks

Hello masters :smile:

Itā€™s possible to use zombies for instruments from VS? Xcode docs says to enable it in Product>scheme>edit scheme>diagnostic>Enable Zombie Objects or add NSZombieEnabled=YES to environment variables section. Both are in xcode available by running xcodeproj. So questions is, if Iā€™ll enable it in xcode, compile with VS then it should works? I cannot manage it either do not have idea where to set NSZombieEnabled in VS. Itā€™s even possible?

b.r.

NSZombieEnabled isn not currently exposed as option in VS, iā€™m afraid. Your best option would be to run in Instruments w/ the Zombies template. NSZombieEnabled is a simple environment variable, so you can also set that yourself manually when running your app from Terminal, say.

Please can You show me how? Iā€™m not mac/xcode expert. Iā€™m trying to find problem in my app. It crash after 10 min. of activity. I realized that strange crash is related to out of memory. I did some test and I donā€™t understand why instruments report leaks for this project. I even put code in __autoreleasepool.

Zombies.zip (117.2 KB)

Itā€™s simple loop with create and destroy 10000 object. Instruments report 92415 leaks. In my app instruments alloc 35 GB of ram after 20 sec. of work, so is not possible to trace it, thatā€™s why other test.

[EDIT]

I did same project in pure Objective-C and it didnā€™t leak. Did same iterations and Objective-C persistent mem = 1,5MB, RO = 17,01MB and 3 huge memory leaks.

iOS app: testapp2.zip (15.5 KB)

Change iterations in RO project to same as in Objective-C to compare results.

b.r.

Okay, here is best one example. Definitelly is something wrong with no mem release. Simple unlimited loop in thread which create class which alloc array of ~1MB RAM, add to NSMutableArray and right after remove and do null to array. ARC should do rest work. For better safety I wrap code with __autoreleasepool. App will work for few sec. and will close. VS will log ā€œReceived memory warningā€. Simulator will eat > 3 GB of RAM. Maybe Iā€™m doing something wrong, but memory shouldnā€™t be auto freed? Same logic works perefectly in xcode and all app take 11MB. Of course tested on real device and result is same - out of memory and crash after few sec.

Zombies2.zip (118.9 KB)

b.r.

I think youā€™re confusing something. Zombies and Leaks are the opposite. In particular, when you run in Zombie mode you cannot judge your apps memory footprint, because Zombie mode keeps all objects around, so by definition memory usage will keep going up and up and up.

A memory leak is an object that never gets released, even though nothing uses it anymore. These commonly happen with Retain Cycles. See here. A leak will manifest in memory usage going up and up. Typically, there fix will be to use weak references to break the retain cycle.

A Zombie is an object that was released, bu someone isn still holding on to a pointer, and trying to use it after its being released. This usually manifests in an obscure crash (unless running in ZombieEnabled mode, where it will give clean message because the released objects gets kept around.

That said, your project looks fine, that code should definitely not leak, (probably not even without the Auto-release Pools that are in place). Weā€™ll need to debug this, this could be a bug in ARC.

Thanks, logged as bugs://72900

Project are named zombies because I test it for zombies first :slight_smile: Donā€™t take project name as part of issue :slight_smile: I mix 2 things here to not open 2 cases. I test it (and did screenshot) for memory leaks in instruments. I start from zombies, because I know that something is wrong and I try to find why my apps crash sometimes. I judge that I try to access to released object but true was opposite (out of memory).
Anyway looks like ARC is not working here. I did other test with only alloc byte array and is same problem. I didnā€™t find any workaround. Please check it with high priority (if possible), because all apps are affected and depend how much object allocations app do, it will work 1min, 5, 10 or few sec.

I hope You will find solution :slight_smile: I believe in Your power :):slight_smile:

b.r.

Weird. all the memory goes not into ObjC objects at all, but into 1MB chunks created by.

Address Category Timestamp Live Size Responsible Library Responsible Caller

0 0x133a16000 Malloc 1.00 MB 00:02.151.466 ā€¢ 1.00 MB Zombies array_create

definitely sounds like a compiler issue.

sounds bad. Fixable?

When byte table is declared in class, then it leak. When created without class, then is destroyed properly. Similar problem is with NSMutableArray.
Class added to an array will not report mem leak after call removeAllObjects or when is out of scope, but array do not release memory, so it grown and grown till out of memory and crash, but ONLY in case, when string is assigned to class variable which in that class.

private class tt
{
	public string str;
}

// repeat it in endless loop
NSMutableArray ar = new NSMutableArray();
for (int b = 0; b <= 1000; b++)
{
	tt tta = new tt();
	tta.str = "some text"; // >>>>> if string is contant, then no memory problem
        tta.str = b.stringValue; // >>>>> if string is variable, then memory is not released
	ar.addObject(tta);
}

b.r.

Of course itā€™s fixable ;). But this is outside of my area of expertise. The compiler guys will need to look at it.

1 Like

Two bugs have been fixed now as part of 72900:

  • .intValue used to leak when called directly on an integer.
  • [] array doesnā€™t cleanup on class destruction.
1 Like

bugs://72900 got closed with status fixed.

1 Like

Great news !!! :slight_smile: Now left class with string problem (hope is only string).

b.r.

which one is that? I dontā€™ see any with a string in a class?

this one. Class with string variable is not released. No matter if added to NSMutableArray or just instance created. But str value MUST be unique for every new instance to reproduce it. With same string all is working properly. Check comments added to tta.str

private class tt
{
	public string str;
}

// repeat it in endless loop
NSMutableArray ar = new NSMutableArray();
for (int b = 0; b <= 1000; b++)
{
	tt tta = new tt();
	tta.str = "some text"; // >>>>> if string is contant, then no memory problem
        tta.str = b.stringValue; // >>>>> if string is variable, then memory is not released
	ar.addObject(tta);
}

Ah. Itā€™s not really about the string in this case, the boxing call from b to NSNumber(b) wasnā€™t released. that I already fixed.

Aha, so all is fixed then from this post I assume? :slight_smile:
Perfect :bangbang:
b.r.

I think so.

Itā€™s not fixed at all. When __autoreleasepool is used then working properly. Without __autoreleasepool, memory is not released. As sample use same code, just donā€™t use __autoreleasepool

[EDIT]

Small claryfication what is fixed and what is not:

Fixed:

byte array is freed with or without __autoreleasepool

Not fixed:

Class with string method where string is unique for every class instance. Itā€™s only freed, when used in with __autoreleasepool

b.r.