I get frequent memory warnings in my application but I don't know why.
Here is the snapshot of allocation instruments.
I know that we don't have any control over virtual memory assigned to us but I am trying to understand what information does that number 26.50 MB means for a developer.
1. What does a high VM means ? Does it lead to a jetsam ? Is that cause of any other concern ?
2. Is this value dependent on device ?
3. Does a low vm means that your app is memory efficient
4. Does a high VM leads to memory warnings in your app ?
5. What cause this value to change ?
6. What steps should a developer take when they see a high vm for their app (like 300 MB) ?
7. Is VM tracker instrument related to this value ?
Anonymous VM covers a lot of things, some of which are things you want to minimize and some that are generally less important. The short version of "anonymous VM" is that it's addresses you have mapped but not named. Heap allocations get "named" which lets you track them as objects. But there are lots (and lots) of non-objecty things that fall into the "anonymous VM" bucket.
Things allocated with malloc can wind up in this region. But also memory mapped files. Your executable is a memory mapped file, but since it's never dirty, parts of it can be swapped out. So "it's complicated." But in big, vague terms, yes, you do care about this section, but you may not care about all of it very much. Heap allocations tends to track your ObjC stuff. Anonymous VM often tracks things that you don't have a lot of direct control over (like CALayer backing storage).
All that said, the Instruments output you provide doesn't look like any major problem. I suspect it's not indicative of a time you're pressuring memory. You'll need to get yourself into a memory warning situation and see what's going on then, and dig into the specifics of what is using memory.
For much more detail on this, you should watch WWDC 2013 session 704 "Building Efficient OS X Apps" which goes into depth on much of this. While iOS has a somewhat different memory system, and some OS X tools aren't available on iOS, many of the concepts still apply.
Related
I'm definitely confused on this point.
I have an iPad application that shows 'Live Bytes' usage of 6-12mb in the object allocation instrument. If I pull up the memory monitor or activity monitor, the 'Real Memory' Column consistently climbs to around 80-90mb after some serious usage.
So do I have a normal memory footprint or a high one?
This answer and this answer claim you should watch 'Live Bytes' as the 'Real Memory' column shows memory blocks that have been released, but the OS hasn't yet reclaimed it.
On the other hand, this answer claims you need to pay attention to that memory monitor, as the 'Live Bytes' doesn't include things like interface elements.
What is the deal with iOS memory footprint!? :)
Those are simply two different metrics for measuring memory use. Which one is the "right" one depends on what question you're trying to answer.
In a nutshell, the difference between "live bytes" and "real memory" is the difference between the amount of memory currently used for stuff that your app has created and the total amount of physical memory currently attributed to your app. There are at least two reasons that those are different:
code: Your app's code has to be loaded into memory, of course, and the virtual memory system surely attributes that to your app even though it's not memory that your app allocated.
memory pools: Most allocators work by maintaining one or more pools of memory from which they can carve off pieces for individual objects or allocated memory blocks. Most implementations of malloc work that way, and I expect that the object allocator does too. These pools aren't automatically resized downward when an object is deallocated -- the memory is just marked 'free' in the pool, but the whole pool will still be attributed to your app.
There may be other ways that memory is attributed to your app without being directly allocated by your code, too.
So, what are you trying to learn about your application? If you're trying to figure out why your app crashed due to low memory, look at both "live bytes" (to see what your app is using now) and "real memory" (to see how much memory the VM system says your app is using). If you're trying to improve your app's memory performance, looking at "live bytes" or "live objects" is more likely to help, since that's the memory that you can do something about.
Seeing as how I wrote the last answer you linked to, I'll have to stand by that. If you want a total, accurate count of the current memory usage for your application, use the Memory Monitor instrument.
For reasons that I describe in this answer, Allocations hides the memory sizes of certain elements, meaning that its memory usage totals are significantly lower than your application's in-memory size. Many people find this out the hard way when they try to get their application functional on older iOS devices. On the older hardware, you had a hard memory ceiling of ~30 MB, where if you exceeded that your application was hard-killed.
Many developers (myself included) saw that we only had ~1-2 MB of live bytes in Allocations and thought we were good, until our applications started receiving memory warnings and early terminations. If you looked at Memory Monitor, you could see the true in-memory size of these applications being >20 MB, and you could see the applications being terminated the instant they crossed the 30 MB barrier in Memory Monitor.
Therefore, if you want an accurate assessment of your total application memory usage, use Memory Monitor. Allocations is great to find out the specific objects that are in memory, particularly when you use the heap shots to find things that might be accumulating (as leaks, retain cycles, or for other reasons). Just don't trust it when determining your application's actual size in memory.
'Live bytes' means memory allocated by your code (for example by malloc), so you have access to this memory. 'Real memory' shows physical amount of memory used by your app. This include also OpenGL textures, (possibly) sounds from Open AL...
Live bytes is useful to check when you allocate and release memory in your code. Real memory is good indicator for memory optimization efficiency. And it's overhead causes 'low memory' warnings.
This is a follow-up to this question: What could explain the difference in memory usage reported by FastMM or GetProcessMemoryInfo?
My Delphi XE application is using a very large amount of memory which sometimes lead to an out of memory exception. I'm trying to understand why and what is causing this memory usage and while FastMM is reporting low memory usage, when requesting for TProcessMemoryCounters.PageFileUsage I can clearly see that a lot of memory is used by the application.
I would like to understand what is causing this problem and would like some advise on how to handle it:
Is there a way to know what is contained in that memory and where it has been allocated ?
Is there some tool to track down memory usage by line/procedure in a Delphi application ?
Any general advise on how to handle such a problem ?
EDIT 1 : Here are two screenshots of FastMMUsageTracker indicating that memory has been allocate by the system.
Before process starts:
After process ends:
Legend: Light red is FastMM allocated and dark gray is system allocated.
I'd like to understand what is causing the system to use that much memory. Probably by understanding what is contained in that memory or what line of code or procedure did cause that allocation.
EDIT 2 : I'd rather not use the full version of AQTime for multiple reasons:
I'm using multiple virtual machines for development and their licensing system is a PITA (I'm already a registered user of TestComplete)
LITE version doesn't provide enough information and I won't waste money without making certain the FULL version will give me valuable information
Any other suggestions ?
Another problem might be heap fragmentation. This means you have enough memory free, but all the free blocks are to small. You might see it visually by using the source version of FastMM and use the FastMMUsageTracker.pas as suggested here.
You need a profiler, but even that won't be enough in lots of places and cases. Also, in your case, you would need the full featured AQTime, not the lite version that comes with Delphi XE and XE2. (AQTIME is extremely expensive, and annoyingly node-locked, so don't think I'm a shill for SmartBear software.)
The thing is that people often mistake AQTime Allocation Profiler as only a way to find leaks. It can also tell you where your memory goes, at least within the limits of the tool. While running, and consuming lots of memory, I click Run -> Get Results.
Here is one of my applications being profile in AQTime with its Allocation Profiler showing exactly what class is allocating how many instances on the heap and how much memory those use. Since you report low Delphi heap usage with FastMM, that tells me that most of AQTime's ability to analyze by delphi class name will also be useless to you. However by using AQTime's events and triggers, you might be able to figure out what areas of your application are causing you a "memory usage expense" and when those occur, what the expense is. AQTime's real-time instrumentation may be sufficient to help you narrow down the cause even though it might not find for you what function call is causing the most memory usage automatically.
The column names include "Object Name" which includes things like this:
* All delphi classes, and their instance count and heap usage.
* Virtual Memory blocks allocated via Win32 calls.
It can detect Delphi and C/C++ library allocations on the heap, and can see certain Windows-API level memory allocations.
Note the live count of objects, the amount of memory from the heap that is used.
I usually try to figure out the memory cost of a particular operation by measuring heap memory use before, and just after, some expensive operation, but before the cleanup (freeing) of the memory from that expensive operation. I can set event points inside AQTime and when a particular method gets hit or a flag gets turned on by me, I can measure before, and after values, and then compare them.
FastMM alone can not even detect a non-delphi allocation or an allocation from a heap that is not being managed by FastMM. AQTime is not limited in that way.
I have code that has a low amount of active allocations (about 5 MB according to Instruments), but a high amount of system memory usage (over 100 MB). I know the code is leak-free, and I'm not seeing any allocation spikes after some optimization, but I'm still crashing due to the high amount of memory usage.
I Googled around a lot and see that I'm supposed to be using the VM Tracker instrument, which confirms my high memory usage, but I'm not sure how to address this situation. I'm using as little memory as possible, it's still too much on an iPad 1, and I don't have the knowledge or tools to figure out how to get the OS to not mark so much memory as dirty when I'm not actually using it. Where do I go from here?
Use the Profile tool and select memory +allocations. Click the VM tracker and take a snapshots. This results in a list with resident dirty and virtual memory usage per object type. This will give you an indication where to look.
I think the most common problem is that you have a lot of autoreleased objects that reside in the autoreleasepool. The following link explains more on how to handle autoreleasepools:
How does the NSAutoreleasePool autorelease pool work?
How does the iOS platform handle memory-mapped files during low-memory scenarios? By low-memory scenarios, I mean when the OS sends the UIApplicationDidReceiveMemoryWarningNotification notification to all observers in the application.
Our files are mapped into memory using +[NSData dataWithContentsOfMappedFile:], the documentation for which states:
A mapped file uses virtual memory techniques to avoid copying pages of the file into memory until they are actually needed.
Does this mean that the OS will also unmap the pages when they're no longer in use? Is it possible to mark pages as being no longer in use? This data is read-only, if that changes the scenario. How about if we were to use mmap() directly? Would this be preferable?
Memory-mapped files copy data from disk into memory a page at a time. Unused pages are free to be swapped out, the same as any other virtual memory, unless they have been wired into physical memory using mlock(2). Memory mapping leaves the determination of what to copy from disk to memory and when to the OS.
Dropping from the Foundation level to the BSD level to use mmap is unlikely to make much difference, beyond making code that has to interface with other Foundation code somewhat more awkward.
(This is not an answer, but it would be useful information.)
From #ID_AA_Carmack tweet,
#ID_AA_Carmack are iOS memory mapped files automatically unmapped in low memory conditions? (using +[NSData dataWithContentsOfMappedFile]?)
ID_AA_Carmack replied for this,
#KhrobEdmonds yes, that is one of the great benefits of using mapped files on iOS. I use mmap(), though.
I'm not sure that is true or not...
From my experiments NSData does not respond to memory warnings. I tested by creating a memory mapped NSData and accessing parts of the file so that it would be loaded into memory and finally sending memory warnings. There was no decrease in memory usage after the memory warning. Nothing in the documentation says that a memory will cause NSData to reduce real memory usage in low memory situations so it leads me to believe that it does not respond to memory warnings. For example NSCache documentation says that it will try and play nice with respect to memory usage plus I have been told it responds to the low memory warnings the system raises.
Also in my simple tests on an iPod Touch (4th gen) I was able to map about 600 megs of file data into virtual memory use +[NSData dataWithContentsOfMappedFile:]. Next I started to access pages via the bytes property on the NSData instance. As I did this real memory started to grow however it stopped growing at around 30 megs of real memory usage. So the way it is implemented it seems to cap how much real memory will be used.
In short if you want to reduce memory usage of NSData objects the best bet is to actually make sure they are completely released and not relying on anything the system automagically does on your behalf.
If iOS is like any other Unix -- and I would bet money it is in this regard -- pages in an mmap() region are not "swapped out"; they are simply dropped (if they are clean) or are written to the underlying file and then dropped (if they are dirty). This process is called "evicting" the page.
Since your memory map is read-only, the pages will always be clean.
The kernel will decide which pages to evict when physical memory gets tight.
You can give the kernel hints about which pages you would prefer it keep/evict using posix_madvise(). In particular, POSIX_MADV_DONTNEED tells the kernel to feel free to evict the pages; or as you say, "mark pages as being no longer in use".
It should be pretty simple to write some test programs to see whether iOS honors the "don't need" hint. Since it is derived from BSD, I bet it will.
Standard virtual memory techniques for file-backed memory says that the OS is free to throw away pages whenever it wants because it can always get them again later. I have not used iOS, but this has been the behavior of virtual memory on many other operating systems for a long time.
The simplest way to test it is to map several large files into memory, read through them to guarantee that it pages them into memory, and see if you can force a low memory situation. If you can't, then the OS must have unmapped the pages once it decided that they were no longer in use.
The dataWithContentsOfMappedFile: method is now deprecated from iOS5.
Use mmap, as you will avoid these situations.
I was reading an article on memory fragmentation when I recalled that there are several examples of software that claim to defragment memory. I got curious, how does it work? Does it work at all?
EDIT:
xappymah gave a good argument against memory defragmentation in that a process might be very surprised to learn that its memory layout suddenly changed. But as I see it there's still the possibility of the OS providing some sort of API for global memory control. It does seem a bit unlikely however since it would give rise to the possibility of using it in malicious intent, if badly designed. Does anyone know if there is an OS out there that supports something of the sort?
The real memory defragmentation on a process level is possible only in managed environments such as, for example, Java VMs when you have some kind of an access to objects allocated in memory and can manage them.
But if we are talking about the unmanaged applications then there is no possibility to control their memory with third-party tools because every process (both the tool and the application) runs in its own address space and doesn't have access to another's one, at least without help from OS.
However even if you get access to another process's memory (by hacking your OS or else) and start modifying it I think the target application would be very "surprised".
Just imagine, you allocated a chunk of memory, got it's starting address and on the next second this chunk of memory is moved somewhere else because of "VeryCoolMemoryDefragmenter" :)
In my opinion memory it's a kind of Flash Drive, and this chip don't get fragmented because there aren't turning disks pins recording and playing information, in a random way, like a lie detector. This is the way that Hard Disk Fragmentation it's done. That's why SSD drives are so fast, effective, reliable and maintenance free. SSD it's a BIG piece of memory and it kind of look alike.