Xcode Instruments Allocations: Look at Live Bytes or Overall Bytes

XCode Instruments Allocations: Look at Live Bytes or Overall Bytes?

Live Bytes is the current usage and is what you are interested in, overall bytes includes all released allocation. The other thing is to look at the graph and look for peaks. As an example I saw a huge peak of about 27MB in an app I was working on, knowing that I was able to reduce peak memory usage to 8MB.

Also watch over time as you exercise your app, it is possible to have substantial memory growth over time that is not leaked, just not not used anymore.

For a description of the memory columns see Explanation of Live Bytes & Overall Bytes.

Xcode Instrument : Memory Terms Live Bytes and Overall Bytes (Real Memory) confusion

"Live Bytes" means "memory which has been allocated, but not yet deallocated." It's important because it's the most easily graspable measure of "how much memory your app is using."

"Overall Bytes" means "all memory which has ever been allocated including memory that has been deallocated." This is less useful, but gives you some idea of "heap churn." Churn leads to fragmentation, and heap fragmentation can be a problem (albeit a pretty obscure one these days.)

"Real Memory" is an attempt to distinguish how much physical RAM is in use (as opposed to how many bytes of address space are valid). This is different from "Live Bytes" because "Live Bytes" could include ranges of memory that correspond to memory-mapped files (or shared memory, or window backing stores, or whatever) that are not currently paged into physical RAM. Even if you don't use memory-mapped files or other exotic VM allocation methods, the system frameworks do, and you use them, so this distinction will always have some importance to every process.

EDIT: Since you're clearly concerned about memory use incurred by using UIWebView, let me see if I can shed some light on that:

There is a certain memory "price" to using UIWebView at all (i.e. global caches and the like). These include various global font caches, JavaScript JIT caches, and stuff like that. Most of these are going to behave like singletons: allocated the first time you use them (indirectly by using UIWebView) and never deallocated until the process ends. There are also some variable size global caches (like those that cache web responses; CFURL typically manages these) but those are expected to be managed by the system. The collective "weight" of these things with respect to UIWebView is, as you've seen, non-trivial.

I don't have any knowledge of UIKit or WebKit internals, but I would expect that if you had a discussion with someone who did, their response to the question of "Why is my use of UIWebView causing so much memory use?" would be two pronged: The first prong would be "this is the price of admission for using UIWebView -- it's basically like running a whole web browser in your process." The second prong would be "system framework caches are automatically managed by the system" by which they would mean that, for instance, the CFURL caches (which is one of the things that using UIWebView causes to be created) are managed by the system, so if a memory warning came in, the system frameworks would be responsible for evicting things from those caches to reduce the memory consumed by them; you have no control over those, and you just have to trust that the system frameworks will do what needs to be done. (That doesn't help you in the case where whatever the system cache managers do isn't aggressive enough for you, but you're not going to get any more control over them, so you need to attack the issue from another angle, either way.) If you're wondering why the memory use doesn't go down once you deallocate your UIWebView, this is your answer. There's a bunch of stuff it's doing behind the scenes, that you can't control.

The expectation that allocating, using, and then deallocating a UIWebView is a net-zero operation ignores some non-trivial, inherent and unavoidable side-effects. The existence of such side-effects is not (in and of itself) indicative of a bug in UIWebView. There are side effects like this all over the place. If you were to create a trivial application that did nothing but launch and then terminate after one spin of the run loop, and you set a breakpoint on exit(), and looked at the memory that had been allocated and never freed, there would be thousands of allocations. This is a very common pattern used throughout the system frameworks and in virtually every application.

What does this mean for you? It means that you effectively have two choices: Use UIWebView and pay the "price of admission" in memory consumption, or don't use UIWebView.

Xcode Instruments Allocations Overall Bytes Too Large

Overall bytes includes those that have been released and is a running total of what has been allocated to your app during the lifetime of the app. The Live Bytes is the one to really worry about as that is the one that shows bytes that are currently allocated.

Overall bytes could keep going on forever as long as you release stuff and the Live Bytes doesn't go too high then you will have no problems.

From that screenshot live bytes looks ok.

There are more details here XCode Instruments Allocations: Look at Live Bytes or Overall Bytes?

Instruments ObjectAlloc: Explanation of Live Bytes & Overall Bytes

ObjectAlloc tracks all memory allocation and deallocation over the time your program is running.

The Living bytes, or Net bytes is how much memory your application is using at the time you select in the timeline. That will include leaked memory, since leaked memory is never deallocated.

#Living is how many allocations of a certain size/object type happened (and are still allocated). This is very useful when looking for leaks.

For example, if you repetitively perform an action (like coming in an out of a modal view controller), and you see that #Living of an object grows by the same amount each time, then you're probably leaking those objects. You can then confirm by drilling down and seeing the exact line of code that is allocating the objects, and even see the time index each one was created.

Overall bytes includes memory that has been released. It's useful to track that number for performance optimization purposes, but not if you're just trying to see your current memory footprint or look for leaks.

overall bytes in Xcode Instruments reaches 1 GB is that ok?

yes since overall bytes is just the number of bytes that were EVER allocated.

The longer the app runs, the higher the no.

Using the allocations in the Instruments tool

The allocations are useful to show your App memory footprint. If you present a modalViewController and dismiss it (and you repeat it), and you see that your Application live bytes keeps increasing, there's something wrong. Memory leaks is useful, to see memory that was allocated and you lost a reference to it. Using ARC helps, but you can still have memory leaks (circular referencing for example). Allocations also helps you understand where memory is allocated and never released. For example a NSArray full of objects, that you are not using, but you are still keeping alive. For your questions:

1) You should worry about both.

2) Live bytes shows your current application size (virtual memory). Overall application size, is exactly what it says: "The total number of allocations in the selected time range".

You can also check this.

Live bytes are same as Overall bytes for all rows

If you use the Leaks template, the Allocations instrument is initially configured to track only active allocations. When you track only active allocations, the live bytes and overall bytes are going to be the same.

To track all memory allocations instead of only the active allocations, click the Info button next to the Allocations instrument and deselect the Only track active allocations checkbox.

Sample Image

Live Bytes vs Resident Size

A bit tricky here. I ran some tests. A couple of comments:

1- You should always typecast the allocated memory:

char *a = (char*) malloc(1024*1024);

2- If you are allocating 1MB above and I see 1GB in the live bytes, this tells me you are using a for loop (1000 times) like this:

for (int i=0; i<1000; ++i)
{
char* a = malloc(1024*1024);
}

It looks like even though you are allocating 1GB of space and not freeing it; it is showing correctly in instruments - but it is not effectively causing a memory crash because this 1GB space has nothing stored in it. It looks like the compiler might be doing some optimization and ignoring this 1GB and as such there is no memory crash.

3- If you change your code to:

  for (int i=0; i<1000; ++i)
{
char* a = (char*) malloc(1024*1024);
memset(a, 'b', 1024*1024);
}

Here you are just allocating the character 'b' to every byte in the 1GB space. This will cause a memory crash. So my conclusion is that the compiler optimizes empty mallocs.

Hope this helps



Related Topics



Leave a reply



Submit