app works fine on iPad 2, crashes on iPad 3, with low memory warning - ios

as the title says, I have an app which works on iPad 2, but crashes on iPad 3. when running it the console gives me a low memory warning message. When the crash happens I symbolicate it, but there's really nothing that I can relate to the code, like it shows
process name, UUID, rpages, recent_max, [reason] (state)
and under those column headers just hexadecimal stuff, nothing showing method calls or lines in the project.
Any ideas? am I missing some flags in the code that allows for a better crash log?
Thanks.

If you're getting low memory warnings and fail to release enough memory to resolve the issue, your app will almost certainly crash. The thing is, I don't think that the particulars of how or why it crashed can possibly be illuminating. At that point, you're evaluating secondary symptoms. You really need to go back and figure out why you got the low memory warning in the first place and fix that problem.
As Daniel said, you can look at Technical Note 2151, but as it says:
When you see a low memory crash, rather than be concerned about what part of your code was executing at the time of termination, you should investigate your memory usage patterns and your responses to low memory warnings. Memory Allocations Help lists detailed steps on how to use the Leaks Instrument to discover memory leaks, and how to use the Allocations Instrument's Mark Heap feature to avoid abandoned memory. Memory Usage Performance Guidelines discusses the proper ways to respond to low-memory notifications as well as many tips for using memory effectively. It is also recommended that you check out the WWDC 2010 session, Advanced Memory Analysis with Instruments.
So, a couple of thoughts:
Have you looked for leaks? The Finding Leaks article walks you through how to use instruments to find your leaks.
If you turned on zombies, have you turned them off? Zombies is a great diagnostic tool, but just consumes memory.
Have you run your code through the static analyzer (shift+command+B or select "Analyze" on the "Product" menu)? Especially if using non-ARC code, this can find lots of memory issues.
Have you examined your allocations for unexplained increases without offsetting decreases with the Instrument's Allocations tool. Using that, you can run the program, look at the consumption of memory on the graph and see if you see any increases that aren't offset at some point by the corresponding decreases. And if so, highlight those increases in the graph:
For example, when running the Allocations tool, hold down the option key and then click-and-drag with your mouse to highlight a portion of the timeline, to identify what you want to inspect. You probably want to focus on one of your spikes in allocations. For example, I found a bump in my allocations and highlighted it as such (this was a ludicrously simple example where I create a huge array in viewDidLoad, but hopefully it give you the idea):
Note, I find it useful to show the call tree in the lower panel, it's often useful to select "Hide System Libraries", to focus on your code (and "Invert Call Tree", too). And if you double click on the method name in Instruments (in my example, here, it would be viewDidLoad), Instruments will then show you your code that's doing the allocation:

Low memory warnings generate a different kind of log than standard crashes. Take a look at the "Understanding Low Memory Reports" section of this article to understand what happened with your application and how you can debug it using Instruments: http://developer.apple.com/library/ios/#technotes/tn2151/_index.html

Related

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.

Leaking memory in iOS

I ran the instruments 'Leaks' tool to test if my app has any leaks, and it showed me that I have some leaks. I'm not an expert at fixing leaks, I was wondering if
I have a leak, and
What I should do to fix it.
You would appear to have a leak, but it looks modest. You can click on the little arrows next to the memory address and it should take you a screen in which you can drill in and see where that memory was allocated, which is the first step in figuring out why it wasn't deallocated. (I'd start the non-malloc objects, as more often they map more directly to your code and it's easier to diagnose).
But sometimes you'll see modest leaks like this which are, as Mike Robinson said, false positives. And even if it's not a false positive, it could be coming from the OS, itself, not your code. So we sometimes go through an exercise of really stressing the app (e.g. repeatedly running through the portion of the app that seemed to generate the leak) to see how rapidly the leak grows, if at all. It looks like your your leak might add up to less than 1 kilobyte or so, and doesn't continue to grow, you might choose to not worry about it. (Or at least once you've satisfied yourself that there's nothing in your code that causes it.)
Personally, though, I'm less concerned about these modest leaks than the significant growth in overall memory usage. It might just be an appropriate caching of images, or it might be a sign of some abandoned memory (which leaks tool won't show you). I'd try simulating memory warning and see how much of that memory is recovered. You can also drag across the timeline and go to the allocations view, and you can see what accounts for that memory consumption. You might want to make sure you don't have some deeper memory problem unrelated to the modest leaks reported by "Leaks" tool. Not all memory problems appear in "Leaks": The "Allocations" growth can also indicate problems, and I'd be a little worried that you're not seeing your memory usage drop down to some steady-state level.
Apple shared an example allocation graph, advising us to watch out for the red "wasted" memory. The warmup portion is not so critical, nor is the intermediate level (as long as it's not too high), but the growth of the steady state level is indication of a more serious memory problem:
In your case, I'm not seeing the app return to a steady state at all, which is why I'm a tad concerned. But I'm not sure how much you exercised the app or whether you gave it a chance to return to that steady-state.
If you watch (the somewhat dated, yet still relevant) WWDC 2013 Fixing Memory Issues, it will arm you with tools and techniques for diagnosing and resolving memory issues. It is where the above chart came from and describes it in greater detail. Note, the PDF presentation is nice, but the video is much better, as it includes some practical demonstrations for using Instruments. The WWDC 2012 iOS App Performance: Memory is also good. (It looks like there might be problems streaming the videos, but it looks like you can still download it.)

iOS ARC ram grows up only [duplicate]

This question already has answers here:
Problems with memory management, autorelease, permanent heap is sometimes 250+ kb on iOS
(2 answers)
Closed 9 years ago.
Hello my question is maybe General I am not asking for code etc.
I developing only for iPhones with iOS6.1 and above
When I run my application the RAM it uses only grows up(when I switching between views (I have like 15 views)).
However after I ran test with analyzer it didn't find any leaks.
also no leaks were found in instrument leaks.
Despite my application doesn't exceed 20 mb of RAM I am still worried that something may be just not ok there.
I am using ARC ,but the ram still goes up.
Is there any way I can check what can cause 1 sided ram allocation ?
If the memory continues to go up, it could be a variety of different things, but "strong reference cycle" is the prime suspect. Sadly, this won't necessarily show up in Leaks tool in Instruments, either.
Do snapshots/generations in the Allocations tool and identify what's not getting released (notably if it consists of any of your classes) and go from there. Specifically, run the app through its paces, then mark snapshot/generation, do a bit more, and then mark another snapshot/generation. Look at that second snapshot and see what's been allocated (but not released) captured since the prior snapshot, with a focus on your classes. You'll find the culprit pretty quickly that way.
See WWDC video iOS App Performance: Memory for practical demonstration.
For example, here is a healthy app that I profiled through the Instruments' "Leaks" tool, but I'm going to focus on the "Allocations" tool:
In this profile, I waited for the app to quiet down, tapped on "Mark Generation" button (resulting with "Generation A", the first flag in my timeline). I then went to a view and then dismissed it, and did "Mark Generation" again, getting "Generation B". The "Growth" column is telling me that between Generation A and B, 100kb was consumed, but not released. But I'm not worried about this yet because there might be some iOS internal cache of UIKit elements. So, I repeat this process one more time to get "Generation C". Now that's interesting, now reporting a growth of only 8.26kb, which is negligible. This, combined with a clean bill of health from the Leaks instrument makes me feel pretty good about the risk of any serious memory problems.
Now, let's contrast that with some code that has a seriously problematic "strong reference cycle":
Now this is a completely different picture, even though the process was the same "present and dismiss" process, repeated twice. This is now telling me that I had a 14mb growth between generations, and more notably, I can clearly see the problematic growth curve. What's remarkable is that while the Allocations tool is clearly catching a serious problem, the Leaks tool reports nothing.
Now, in practice, the real-world experience with the Allocations tool will probably rest somewhere between these two extremes. Your app may have its own caches or model objects that slowly take up memory, but if you're properly responding to memory warnings, you should be recovering that memory. Frankly, though, most well designed apps should not be generating memory warnings at all (usually accomplished by properly configuring caches, avoiding imageNamed where appropriate, moving to persistent storage for large or infrequently accessed data, etc.). The goal is to get to a point where the app stabilizes around some reasonable baseline memory allocation level, consistently returning back to that baseline.
But it's going to be impossible for us to advise you until you do some basic profiling of your app and diagnose the sorts of memory issues that you're having.

Received memory warning source

After getting numerous memory warnings in the console , I tried using the memory profile tool to understand the root cause. But I don't see any strange behavior in memory allocations.
Is there a way to know what exactly is causing the warning?
Edit:
Print screen of profiler
Thanks for any guidance
sorted By "Overall Bytes" and "Created and Still living"
and added some detail to that:
and the code detail:
There is no single reason for memory warning. First of all you should always profile on real device - never simulator.
Add a profiler gadget called "leaks" to search for memory leaks on profiler while doing profiling.
You can get memory warning depending on a device even at around 10 - 12MB used by your application. Unfortunately there is no official information from Apple how much you can safely use.
In profile check also Total Living bytes. Try optimizing your code with autoreleasepools (if you are doing lot's of object allocation in "for" loops for example.
You can also check in Profile which objects takes most space.
Without real project to play with - it will be really hard to point a problem. Depending if it's a game and how much images you're using - problem may be different.

Ambiguities in using Instruments for iOS Development

I am Profiling an Application with Instruments. The profiling is done using Allocations Tool in two ways:
By choosing Directly the Allocations when I run the App for Profiling
By Choosing Leaks when I run the App for Profiling.
In both the cases , I had Allocations tool enabled for testing. But surprisingly , I had two different kind of Out put for Allocations at these instances.
Are they supposed to behave differently? or this is a problem with Instruments.
The time I Profile the with Leaks Tool:
In Allocations Graph:
1. I get lot of Peaks in Graph, The Live bytes and overall bytes are same.
2. I get the Black flags (I think it alarms about memory warning) after 1 minutes usage. Then after a set of flags appearing, my App Crashes. (This happens at times, even when directly run the App in Device)
The time I Profile the with Allocation Tool:
In Allocations Graph:
1. I do not get peaks often as it was in the above case. The Live bytes was always way less than Overall bytes.
2. I have used for over 20 minutes and never got Black flags.
One fact I came to know is that, when Live bytes and overall bytes are equal, the NSZombieEnabled could be enabled.
Have any of you ever encountered this problem.
UPDATE 1:
I faced another problem with first case. Whenever I profiled after a short duration (compared to profiling in second case), the app got lots of Black Flags and my App Crashed. (Due to Memory warning)
And when I tried the similar step by step use of Application my Application did not crash and got no flags.
Why this discrepancy?
In the first case, you are only tracking live allocations because the "Leaks" template configures the Allocations instrument that way. In the second, you are tracking both live and deallocated allocations. (As CocoaFu said).
Both are useful, but for slightly different reasons.
Only tracking live allocations (in combination with Heapshot Analysis, typically), is a great way to analyze permanent heap growth in your application. Once you know what is sticking around forever, you can figure out why and see if there are ways to optimize it away.
Tracking all allocations, alive and dead, is a very effective means of tracking allocation bandwidth. You can sort by overall bytes and start with the largest #. Have a look at all the points of allocation (click the little arrow next to the label in the Category of the selected row), and see where all the allocations are coming from.
For example, your graph shows that there are 1.27MB of 14 byte allocations -- 9218 allocations -- over that period of time. All have been free()d [good!], but that still represents a bunch of work to allocate, fill with data (presumably), and free each one of those. It may be a problem, maybe not.
(To put this in perspective, I used this technique to optimize an application. By merely focusing on reducing the # of transient -- short lived -- allocations, I was able to make the primary algorithms of the application 5x faster and reduce memory use by 85%. Turns out the app was copying strings many, many, times.)
Not sure why your app crashed as you described. Since it is a memory warning, you should see what is most frequently allocated.
Keep in mind that if you have zombie detection enabled, that takes a lot of additional memory.
Depending on the way Allocations is instantiated there are different options. Check the options by clicking the "i" symbol in the Allocations tile.
Yes, I find this annoying also.

Resources