How to programmatically purge/clean cocoa application memory? - objective-c

I'm working on a Mac app. Initially monitoring Xcode's memory report while I ran my app showed showed the memory was just ramping up crazy. I used Instruments and profiled my app for allocations and leaks. Turned out there wasn't much leaked memory as you would expect due to strong reference cycles etc. However there was a lot of abandoned memory. By following the stack trace that lead to my code I have fixed by 70% using autorelease pools etc. Still the remaining 30% of abandoned memory seems to point system calls.
Now I have two questions based on that I have two questions
1) I want to fix the remaining 30%. How can I get rid of abandoned memory? I have already used Instruments and know exactly where those system calls are spawned but still dont know what to do to have that memory be cleaned up. (using ARC no manual retain/ release and autorelease doesn't seem to make a diff.)
2) After I know whatever my application was doing has completed and there is no need for any memory to be there (just like the application first started) I want to get rid of all memory that my app has used up. This I plan to use as a brute force approach to clean up all memory just like the system would if the user closes the app or turns off the system.
Basically if I know where my apps memory is in the file system I'll just programmatically call purge command on that or something similar. Because at this point I'm 100% sure nothing needs to be in memory for the app except for the first screen that you would expect the first time you launch the app.
I read this, this, this and this but they weren't helpful.

Related

Cocoa core data app cycles rising memory

I'm working on a cocoa app that receives and stores large amount data into core data ( > 500K objects with many reverse relationships). The app has to constantly run in cycles. The problem i encounter is after each cycle the allocated memory is growing by 20-40 megabytes (as indicated by xcode; of course, same tendency showed by activity monitor).
What i have so far:
wrapped methods that insert objects into context in autorelease pools;
reset context, undoManager nil, stalenessInterval 0;
recreate persistent store coordinator on cycle completion (remove-add the store);
many hours of profiling, but could not find leak causes
Thought i'll appreciate advices if this list of actions can be improved, my main question is how should i deal with system memory, which my app will eventually eat up. Because it's possible i wont be able to optimize my code any more. I must not allow the app to crash due to not enough memory; so the way i deal with it now is i relaunch the app if its memory allocation reaches some hardcoded value (lets say, 1 GB).
I don't like this solution, so hopefully someone can advice me on appropriate way to handle this. Or on ways experienced people handle such situations. Thanks
UPDATE
Adding snapshots from instruments and xcode's memory debug gauge when first cycle has finished.

Is too much memory allocation in Instruments bad?

I am playing around with Instruments. And I just recorded/profiled for memory leaks, I had very few memory leaks, but an overwhelming amount of allocations just keep going even when my app just opened. Here is a screenshot after using the app for less than 10 seconds.
And as I keep using the app it just keeps increasing and increasing.
The weirdest part is most of the allocations are coming from classes I don't know like:
Foundation
Altitude
lbdispatch.dylib
But it could be from the SBJson and the other classes I imported and added for JSon and XML.
But is this a lot of memory allocations? Is too much bad???
Yes and no, it depends on what you are doing, if you allocate for example a lot of strings, lets say you allocate 1000 strings these allocation perse are not bad, but it depends on your logic view of your application, if you really need all the strings at once and you need them to be allocated and alive through all the steps of your application, then you dont have anything to do, your application just needs alot of memory,
However on the other hand, you may find some other ways to logically structure your application, like for example you could only allocate each of the 1000 string once you need it.
A very abstract answer is, if your app requires a lot of memory and there is no way to use some techniques such as lazy loading, or caching, then you dont have any other solution
But if you can restructure your application to use lazy loading, caching, allocation pools it would bee better
Please note: that you could let iOS sdk help you, by implementing correctly the memory warning callbacks in your application, in such a way that whenever you receive a warning, you start releasing any resource that you dont currently need
Also, do you have Zombies on? Zombies default to not actually removing any allocations, so memory is never deallocated. Always test for memory leaks with Zombies off.

iPhone4 iOS5 ARC how to profile memory?

I'm trying to debug a mysterious app crash that happens after running the app for a few hours.
My hunch is that this may be memory related, as I've not done any memory optimization since starting to build my app.
I'm looking at my application with the "allocations" instrument and I see these numbers:
All allocations 4.70mb
Living 51072
Transitory 357280
Overall Bytes 100.23mb
Overall 408000
Which is the important number here? Does my app take 4.7 Mb of memory or 100 Mb? At which point should I be concerned about my app being killed for memory reasons? I want to avoid premature optimization :)
Since I'm using ARC and TabBarController, most of the controller related memory seems to be out of my hands, unless I find out how to create a tab and lazily init a controller when that tab is first touched.
Thank you!

Memoryusage drops after a week

I have this app written in VB.Net with winforms that shows some stats and pictures on a bigscreen monitor. I also monitor the memory usage of sad app by using this.
Process.WorkingSet64
I know windows does not always report the correct usage but I just wanted to know if I didn't have any little memory leaks which I had but are solved now. But the first week the memory usage was around 100MB and the second week the memory usage showed around 50MB.
So why did it all of a sudden drop while still running the exact same code?
I can hardly imagine that the garbage collector kicked in this late since the app refreshes every 10 seconds and it has ample time in between those periods to do it's thing.
Or perhaps there is just better way to get memory usage for a process that is more reliable.
Process.WrokingSet64 doesn't report the memory usage, it omits the memory that is swapped to disk:
The value returned by this property represents the current size of working set memory used by the process. The working set of a process is the set of memory pages currently visible to the process in physical RAM memory. These pages are resident and available for an application to use without triggering a page fault. (MSDN)
Even if your system was never low on free memory, you may have minimized the application window, which caused Windows to trim its working set.
If you want to look for memory leaks you should probably use Process.PrivateMemorySize64 instead. Your shared memory is going to contain just executable code and it's going to remain more or less constant throughout the life of the process, so you should focus on the private memory.

Why is my app getting didReceiveMemoryWarning and gets killed although memory is constant and there is enough memory available?

I'm having strange effects with my app. I implemented my own PDF viewer. It shows ONE page at a time. Using Instruments Activity Monitor I see that my real memory is constantly at around 50MB.
After switching pages forth and back a couple of times I receive a memory warning level 0.
I do my best to react on it and sacrifice the low-res background image I'm rendering first to show something until CATiledLayer catches up.
Does not help. A few pages later I get memory warning level 1 and level 2 and after a few more pages my app gets killed with reason "9". Memory NEVER goes above 50MB!
Why do I get those warnings in the first place? There IS enough memory available.
This is happening on on iPad running iOS 4.3.
I don't think there's anything mysterious going on here -- which I'm sure is not what you wanted to hear. There are no absolute figures of "safe" amounts of memory to use. The rule is: when the OS tells you you're using too much, use less. It will jettison background processes first and in preference to your foreground app but there are still limits.
In the "olden days," you used to be lucky to get 20Mb. I'm sure you can safely get more than that on an iPad but, apparently, it's less than 50Mb.
You don't say how much memory you free by releasing the background image, but it seems that you need to be caching less data. You might also want to check Leaks (also in Instruments) to make sure you're releasing the objects you think you are.