How to detect stuff that has not been released properly - ios

Writing a program for the iphone. Realized that I forgot to release an object, but there was really no indication that the object was not released everything just worked.
What is the best way to track something like this down? Is there a way to see what objects still exist in memory when the program exits out?

Take a look at the Leaks tool in Instruments.

Strictly speaking, when the program exits, it doesn’t matter what you’ve left in memory: the system frees everything that your application allocated throughout its lifetime. Since iOS 4, though, apps usually just get frozen in the background and don’t exit until the system kills them to free up memory. To avoid that—and to reduce your app’s memory footprint, which is important while it’s running—you should, as highlycaffeinated and Daniel suggested, use Instruments’s Leaks tool to check for objects that aren’t getting deallocated properly.

When the app exits, anything in memory is destroyed by the system (not deallocated-- but just outright destroyed when the address space is given back to the system).
While others have suggested using the Leaks tool to find leaks in your app, Leaks won't find many many kinds of memory accretion. If an object is allocated, shoved in a cache somewhere, then the key to that object in the cache is lost, the object is effectively leaked (can never be used again) but won't be find by Leaks because it is still connected to your viable object graph.
A better bet is to use Heapshot analysis to see how your app's object graph grows over time. I wrote up a tutorial on using Heapshot analysis that you might find useful.
If you want to grab a snapshot just before your app exits, then put a sleep(1000); into your code in either an application termination handler or somewhere else that is executed just before the app exits.
Just remember to remove it before shipping a production build. :)

Once an application quits - you don't have access to that. But Instruments (an XCode tool) can look for memory leaks.

Nothing exists in memory when pprogram exits. But you can start with analyzing your code (Product -> Analyze) and running it with (Product -> Profile) Allocations or Leaks in Instruments to find memory management issues.

Related

didReceiveMemoryWarning: what type of memory?

I have a base cordova app, with some objective-c code around cordova's framework. Sometimes I've didReceiveMemoryWarning notification, but I don't understand if the problem is the javascript inside the UIWebView or other.
The documentation says:
Your app never calls this method directly. Instead, this method is called when the system determines that the amount of available memory is low.
But my question is: what type of memory?
RAM? Heap allocations? Something else?
RAM, it is for RAM, if your app consuming more memory without realising it, and no memory to remain to process any more thread then, this didreceivememorywarning get called by system.
You should profile your app with Instruments and you'll get a better picture of what's consuming memory.
The memory issue represents to RAM, generally we are creating the app using different objects, and these objects take some memory to process the required task. If we aware about them we can easily manage the memory but sometimes for beginners it is not managable to debug the memory, and didReceiveMemoryWarning occured. We can diagnose or debug this issue by instruments.

Using instruments to find memory leaks

I've tried to read almost every decent tutorial in the internet, but still can't understand what is really happening here:
I've "Hide System Libraries" and "Invert the call tree", but I do not understand how to find actual code responsible for for example this leak. Any tips are appreciated. May be I am missing something obvious. I am getting hundreds of leaks, however I am using weak in closures, I do not have classes referencing each other etc. But it looks like I am missing something fundamental.
The problem shown in your screenshot is Instruments can't find your app's debug symbols. Instruments is showing memory addresses instead of function names. You are not going to be able to find the source of your memory leaks in Instruments without function names, even if you invert the call tree and hide system libraries.
Make sure your project is generating debug symbols. Check that the Generate Debug Symbols build setting is set to Yes. If your project is generating debug symbols, Instruments may be unable to find the dSYM file that contains the debug symbols. In Instruments choose Instrument > Call Tree > Locate dSYM. The dSYM is usually in the same directory as the release version's application bundle. The following article has additional information:
Instruments: Locating dSYM Files
Memory leaks can be difficult to track down. This is likely going to be a time consuming process, so be prepared. In the end, there is usually a lot of trial and error with debugging memory leaks. The "Memory Leaks" instrument has actually only detected one leak for me in the past. I've always had to track them down myself using the "Allocations" instrument.
One of the things that has helped me in the past is to start by trying to figure out what objects are actually being leaked. Click on the allocations instrument (the row above "Leak Checks"). Now try sorting by number of objects released or amount of memory used. See if there are any objects that have a count of 0 released when they shouldn't be sticking around. See if there is an object type that is taking an abnormal amount of memory.
Memory leaks are always due to developer mistakes with memory management. There are some minor memory leaks that exist in some of the lower level private APIs in Foundation and UIKit. At those lower levels, they are dealing with a lot more manual memory management, so its much easier to make tiny mistakes. You can't really do anything about those, but they are relatively rare.
If your application is working just fine, you may not need to worry about fixing these. There is some cost benefit analysis you want to do here. If this isn't impacting performance or stability, is the time investment in fixing these right now worth the minor benefits it will provide you and your users?
However it is worth nothing that memory leaks can add up, so if a user has your app open for a long time, the amount of leaked memory will eventually become a problem if you continue to leak more objects over time. At some point the application will crash and the user will have to re-open. But if your memory leaks are small enough that this doesn't become an issue unless the app has been open for HOURS, is it really that much of a problem anyways? That's always a judgment call on your part.

possible to leak in-memory data from one ios app to another?

Preface: I'm not an iOS developer and know next to nothing about the iOS security model. So forgive me if this question is truly dumb. :)
Consider an app, called MyApp, that does the following when launched:
Dynamically allocates a chunk of memory, say using malloc().
Loads some sensitive data over the network and stores it in that chunk of memory.
Sits there doing nothing.
Now consider the following scenario:
User launches MyApp.
User closes MyApp.
User launches SomeOtherApp.
My question: If SomeOtherApp also dynamically allocates memory is it possible that one of the buffers returned by the OS will contain the sensitive data placed there by the (now closed) invocation of MyApp?
Or are the contents of RAM treated as part of the sandbox in which an app runs?
Theoretically once the user closes the app (you have to make sure that the app is closed and not just running in the background) the memory that was allocated to that process is deallocated and returned.
To quote from a tutorial on ARC:
"With Automatic Reference Counting enabled, the compiler will automatically insert retain, release and autorelease in the correct places in your program. You no longer have to worry about any of this, because the compiler does it for you."
So when an app closes, all references to any objects which had some sort of memory allocation will be cleared because there will be no objects to reference when the app is not running.
The reason that I say that you have to make sure that it is closed is because some apps, by default, will not close when you press the home button, but will in fact continue to run in the background. This might cause a potential security threat, but unlikely. To ensure that NO memory is still being held on to by that app, make sure that it actually fully closes each time. Make sure that the code is done right and that the person who is writing it, knows and is keeping track of the memory that he allocates.
If security is a big issue, then make sure that all of the memory that does get allocated get properly deallocated in your code. Then make sure that you do an insane amount of testing for memory leaks and whatnot to make sure that no object is left lying with some amount of memory.
I would just like to say that I am not a professional on memory management of even ARC, so it would be best to check with a couple other sources to ensure that my answer is correct.
If I have spoken in err, someone hit me.

Knowing where memory is being allocated using FastMM

I am trying to debug memory usage in a large application using Delphi 7. I was able to installed fastmm debug full dll and with it solve some leak problems.
I also installed the memory usage tracker, allowing me to see which blocks were allocated and of what size they are.
My question is, is there a way to find out where the blocks were allocated? I know it is possible because if the memory wasn't freed a stack trace gets printed. Is there a way to 'poke' at fastmm to get it to print the stack trace for a given allocation?
Side question: if the start address of an allocation is known, is there a way to find out which class the object is? (assuming that the allocation was for a object.
You can either:
try to use LogAllocatedBlocksToFile procedure. If its ALastAllocationGroupToLog param is less than AFirstAllocationGroupToLog or is zero, then all blocks along with their allocation call stacks are logged. However, if your app has many memory allocations, prepare to long waiting. I experienced about 4 hrs wait time and 1.5Gb resulting file. (Side-note: use glogg to view such large files)
modify FastMM4.pas so implementation's LogCallStack will be visible in interface. Or you can try to use it directly from FastMM_FullDebugMode.dll
On the side question: try to use DetectClassInstance function.
If you use FullDebugMode and enable the conditionals that will write the data to a file, then you should get exactly what you're asking for. It will write out a stack trace for every leaked allocation when the program shuts down. (If you're debugging a program with a lot of memory leaks, this can take a while. I've seem it make shutdowns last for 10 minutes or more if the leaking item is a container that holds lots of other objects.)
Considering you said in a comment that the app's memory gets cleaned up nicely on app's closing for me sounds you're looking for logical memory leaks - in other words: objects that are alive more time than needed but when the time arrive for finish the app they are cleaned because exist code to clean them.
Example:
Create an TForm using the Application as owner and the variable that references it is the global one that Delphi creates when create the form's unit.
Config the Form's CloseAction to caHide (in the OnClose event)
Show the form, operate on it
Close the form and never more use it until the app closes
Close the app, which makes Application clear all the objects it owns
So you have an logical memory leak but not an physical memory leak - which is the kind that FastMM can easily detect. Since you not intended that our hypothetical TForm live until the application finish, it semantically leaked but since it is referenced and there is code that destroys it at the end of application, to FastMM is a normal allocation.
That said appears you need not the memory dump of the memory manager, but an memory profiler.

iOS : ARC, not freeing memory

I've kind of a weird issue with my iOS app.
after a while my app goes low in memory so memory warning, everything seems to be fine, but when I check the memory usage I noticed that all the calls to viewDidUnload didn't free up lot of memory, so after a few click in my app, it goes again in memory warning, everything seems to be fine again, but not a lot a memory have been released, so it goes again in memory warning faster, and then it crash (after the third memory warning most of the time). this crash is random : app freeze, app leaves, my debugger says app paused, but no bad access or sigbort, no zombies.
my guess is that memory warning can't free up enough memory has it should.
(I checked all my viewDidUnload and make nil every objects that are allocated in viewDidLoad)
Any help will be usefull !
thanks a lot.
So I managed to work with my issue.
I wrote "-(void) dealloc" methode in all my controllers and check if I enter in it as I should. (on pop controller, dissmiss etc..)
Every time it didn't, I do step by step in the controller to see what was retaining my controller from beeing dealloc.
most of the time it was some property that was not in "unsafe_unretained"
delegate that was in "ASSIGN" (and should not be in assign but in unsafe_unretained)
(heritage from non-ARC project...)
I also had some strange controller with XIB that was not deallocated even if empty.
I rebuild new one step by step with copy/paste and finaly with exactly the same code, the new controller was released, with no visible difference between then !!! gnneee
at least I know how to debug that kind issues now...
I don't think there's any way to give a specific answer without more data so the best I can do is suggest that you stop guessing what might be happening with your app and learn how to measure what is actually going on. Run your app under Instruments and you'll be able to check for leaks and also actually see what classes are responsible for the most of your application's memory footprint.
You should make sure you know how to use both the Leaks instrument to identify leaked object but also the Allocations instrument to identify orphaned (but not leaked) sets of objects which should have been released or just cases where your app is not responding to memory warnings as you expected.
https://developer.apple.com/library/ios/#documentation/developertools/conceptual/InstrumentsUserGuide/AboutTracing/AboutTracing.html might be a good place to start and there are a number of tutorials available as well; http://www.raywenderlich.com/2696/how-to-debug-memory-leaks-with-xcode-and-instruments-tutorial and http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/ are among the first results I saw.
Vassily,
First, if you aren't yourself releasing extra memory, the the -didReceiveMemory warning does you no good and the OS will keep asking for memory until you are killed. This sounds like it is your problem.
Second, if that isn't the problem then you are probably getting terminated due to the size of your resident memory partitions. Make sure you look at your VM allocation in Instruments. I expect the MALLOC_TINY or MALLOC_SMALL both have greater than 5 MB resident and dirty footprints. Due to the nature of small allocations these VM regions will never shrink. The only option you really have is to not create a lot of small items in the first place. This is really only something you can address by changing you code's algorithms to use less memory.
Andrew

Resources