Question about Element's ARC

Hi carlo,

Could you run these two test projects:

  1. RO C# one: Elements_MemoryLeakTest.zip (111.9 KB)
  2. Objc one: Objc_MemoryLeakTest.zip (34.9 KB)

I think they have the equvilent test code. In my test result, the first one will always print logs as:
before set nil
after set nil
BigObject dealloc!!

But the second one will always print logs as:
before set nil
BigObject dealloc!!
after set nil

Can you reproduce this?

I can check tomorrow; however that is NOT related to the auto release pool. Odds are if you put:

            var a = createObj();

            NSLog("before set nil");
            a = null;
            NSLog("after set nil");

in a block:

{
            var a = createObj();

            NSLog("before set nil");
            a = null;
}
            NSLog("after set nil");

it does act the way you want it to.

As discussed before, in elements we release local cars when they go out of scope, not right after they are accessed the last time. This easily explains the differences you are seeing?

Also, again I asks, why does this detail matter, except as a purely academic discussion? Nothing is leaked, it just gets released a tiny bit later than you would like it to.

Strange, that’s not true for me. It still acts the same way as before in Elements 8.2.88.1879.
Is it sth related to the new bugfix about memory leak?

btw, I do all tests on iOS 9.1 64bit.

I’m not sure the explanation will be that simple, because it’s the same test result if I add the ((objc_precise_lifetime)) attribute for variable a in objc.

I think this “returned value” optimization is indeed important for ARC, otherwise Apple won’t make those two related runtime methods for objc at the beginning.
So if this optimization does not work as expected in Elements’ ARC, it’s worthy to be investigated.

bugs://73551 got closed with status testcaseerr.

So, what’s happening here is a codegen related issue. the calls used by objc (specifically objc_autoreleaseReturnValue) scan the caller address and look for objc_retainAutoreleasedReturnValue immediately following the call. Depending on the location it would or would not immediately follow it.

(like if you were to insert an NSLog before your createObject call it would probably do what you want)

I’m going to see if i can force llvm generate things in exactly this order.

bugs://73551 got reopened.

bugs://73551 got closed with status fixed.

I do have to note 1 thing. All of this ONLY works in optimized mode (same goes for objc when enabling matching options: -O0 -fobjc-arc-exceptions -fobjc-arc)

OK thanks!
I’m not so familiar with objc compile options yet. Is “-O0 -fobjc-arc-exceptions -fobjc-arc” the default options for a new XCode iOS objc project in debug mode? “-O0” seems the loweast optimize level.

Wel O0 is default. Arc too i think for new projects. Arc exceptions not

Hi carlo, is this fix included in 8.2.88.1887?
I’ve tried the test project (Elements_MemoryLeakTest.zip) in 8.2.88.1887 with Release build ( “Optimize code” option is checked ), and it’s the same result as before (returned object won’t be deallocated until the end of an ARP).

I don’t believe so, no. This probably was fixed for the 8.3 branch. was tis listed in the change log?

indeed it was 8.3

Looking forward to 8.3 beta, thanks :+1:

Probably next week ;). For now we want peopl focused on testing the game for 8.2 so we can find any last issues, before RTM (planned for Friday).

bugs://73551 got reopened.

bugs://73551 got closed with status fixed.

I found it. There’s 1 thing that has to changed in your testcase to make it work: CreateObj should be protected/public really anything but private. If it’s private it will get inlined and the llvm inliner doesn’t currently collapse these two.