Good afternoon,
I was doing some Instruments testing on my iOS app that I'm about to release, but I noticed some VERY strange memory leaks, that appear to be coming from System libraries.
When I ran Instruments I got this leak:
Which is extremely weird from my point of view! I went to the Call Tree of these leaks and they all appear to be deep C++ system calls.
What confuses me even more is that this project has ARC enabled, and I ran it through the Analyzer and no problems showed up.
Even more weird is that this DOES NOT happen on the Simulator, nor on my real iPad, but on my iPhone this problem happens.
And when I check "Show Obj-C only" and "Hide System Libraries" the call trace disappears which leads me to believe my code is not responsible for the leak.
Why is this happening and what can I do to fix it?
Thanks guys.
The above leak is not a leak inside your app and it is inside apple's library which you dont have to worry about. If you have fixed all the leaks inside your app, you are fine. Apple will not reject your app just because of this small leak.
Related
After spending several hours on finding some leaking NSCFStrings in Instruments I seem to have realized that calling Cocoa's -animator proxy is causing this.
It is always reproducible: Just create a new Xcode project, add a new NSTableView in IB, fill it with some test data and run Instruments with Leaks. Once you hover over the NSTableView so that the scrollers fade in and out, you'll notice at least one leaking object in Instruments.
Although I've already filed a bug to Apple, can anyone confirm this leak?
Demo-Project: https://www.dropbox.com/s/lszveuwrsuaxxg5/TableViewMemoryLeakStackOverflow.zip
Screencast: https://www.dropbox.com/s/vqtwbkus3jygdb3/ProxyAnimatorMemoryLeak.mov
This bug was resolved in OS X 10.9.3.
I am new to ios development. I am having a very serious issue now. My application is almost complete but it crashes very often due to memory warning. The memory warning is received whenever I present a new view controller on the top of the existing view controller. The custom view class adds UIWebView to its view when the new view controller is loaded.
I tried to debug the memory allocation with instruments but do not have any idea on how the memory is being allocated. The screenshot of the heapshot analysis shows bunch of non-objects as in the figure below and when I see the stack trace it points to adding the webview.
Please suggest me how I have to debug. What does these non-objects point to and how should I deal with them. I thank you for your suggestion and help in advance.
Non-object allocations are almost always used as backing stores within objects. I.e. an NSMutableArray will often be backed by several malloc()'d buffers that show up in non-object allocations in instruments.
Unless the non-objects are the only thing showing up as allocations in Instruments, you can ignore them.
Instead, focus on allocations of a specific type. Anything else in that Heapshot iteration? Looks like there is a CardScrollView in that backtrace on the right. Are they going away correctly?
I am experiencing some odd behaviour - I have a property "key" being released in an object's dealloc, this works fine when I am debugging the app on my iPad.
But, when I launch the app "normally" i.e. without running it via XCode, it crashes immediately and from looking at the crash log, I can see it's because the "key" property is throwing an BAD ACCESS error where it is being released.
Does anyone know why my app might behave differently in these two scenarios?
I can obviously fix the bug, but I am not sure even why it is happening...
Right now my app should only supports Portrait. On Summary/Supported Device Orientations I have only selected Portrait so I'm hoping that my app will not rotate. I was testing the app on a device and suddenly I'm getting the following error randomly:
[UIButtonContent deviceOrientationDidChange:]: unrecognized selector sent to instance
It happens when I rotate the device SOMETIMES, is not consistent, and is not always over UIBUttonContent. I supposed that if I only select Portrait, deviceOrientationDidChange should not be called or should be ignored.
Other times my app crashes with an EXC_BAD_ACCESS (code=1, address=something) but it happens when I rotate the device so I'm guessing that both errors are related.
I don't know what to do with this, it's hard to debug because I don't have feedback, the All Exceptions Breakpoint is not being called, so I don't know where and exactly why this is happening. Any idea on how to debug this is welcome.
These are the classic signs of a memory management error. You have over-released some object and it has been deallocated while something else still references it. Later, something messages it. In some cases a new object has taken its place, but that object doesn't understand the messages it's receiving. In other cases, there's no valid object and you get a crash.
Edited to second the advice to use the Zombies instrument to find the over-release.
Do you have a class that should be called with deviceOrientationDidChange:? When this happens, it usually means that you have a dangling reference to a deallocated object. You should try profiling your app with Instruments in "Zombies" mode.
I solved this issue a long time ago, but I think is good to share what actually helped me on this case.
After trying everything with no results with Instruments I started debugging old-school. I had an idea of "where" the error was so I just commented all the code on that section. I was right, the bug just disappeared along with some functionalities. After that I made "binary uncommenting" (uncomment one half) till I got the bug line. It was a third party library, I had an object that was not being released properly.
Not sure why, but making a simple [[NSOpenPanel openPanel] runModal]; creates a memory leak - seen in Leaks Instrument.
Seems off.
It's an auto-released object, shouldn't it be automatically released after ARpool is drained?
Is there a way to fix this?
NSOpenPanel is a singleton, which means you always get the same instance of the object every time you use it. This means that the first time you call [NSOpenPanel openPanel], an instance of NSOpenPanel is created and not released.
This is not a leak, it's an optimisation. However, sometimes the Leaks instrument picks up such once-only instantiations as leaks because the instances are (by design) never released.
NSOpenPanel is such a widely-used and tested class that any leaks in its standard implementation are unlikely to exist.
NSOpenPanel is not a singleton. It may have been at one time but looking at the latest NSOpenPanel.h file makes it explicitly clear it is not a singleton or at the very least Apple doesn't want you taking advantage of this implementation detail.
As for the leak, I was confused on when I should release my open panel and was retaining it. From the Using the Open and Save Panels section of the File System Programming Guide your life is a lot easier in 10.7 and above:
Important: In OS X 10.6 and earlier, you must retain an open panel prior to displaying it and release it when you are done with it. Because the openPanel method returns an autoreleased object, the panel is normally released shortly after it appears on screen. Retaining the panel prevents it from being deallocated and dismissed prematurely. You do not need to retain the panel if it is attached to a window and you do not need to retain the panel in OS X 10.7 and when using ARC.
Once I stopped retaining it things got easier and became a lot easier :)
Instruments is not perfect at detecting leaks - particularly for autoreleased objects, and has a tendency to have false positives. You might try creating a new NSAutoreleasePool, then draining it when you are finished with the NSOpenPanel to force release early - but I suspect you don't actually have a leak. If you are confident that the code looks good and it is autoreleased, then its probably fine.
I was seeing "leaks" reported in Xcode's memory graph tool when using NSOpenPanel in an unsandboxed app built on OS X 10.11.6 using the 10.12 SDK and Swift 3.0.1. The "leaks" were reported in PlugInKit classes (PKHostPlugin, PKDiscoveryDriver, etc.) and would show up even if the only line of code was let openPanel = NSOpenPanel().
NSOpenPanel's documentation states
In a sandboxed environment, Open panels are drawn in a separate
process by the powerbox, not by AppKit itself. When the user chooses a
file to open, macOS adds that file to the app’s sandbox.
After I sandboxed the application, the "leaks" did not show up in Xcode's memory graph as the NSOpenPanel implementation code was no longer in the application's address space, so I no longer had to worry about it.