What's the difference between abandoned memory

2020-02-17 08:14发布

问题:

Both are exactly the same thing, except that "abandoned memory" refers to a whole object graph leaked rather than just a single object. Right?

回答1:

First, you need to understand the notion of a "memory object graph" or "application object graph" (or, simply, "object graph" as it applies to allocated buffers). In this case, "object" refers to any allocation in your application, be it an object or a simple malloc()ed buffer. The "graph" part if it is that any object can contain a reference to -- a pointer -- to other objects.

The "live object graph" of an application are all of the allocations that can be reached, directly or indirectly, from the various "roots" in the application. A "root" is something that, on its own, represents a live reference to an object, regardless of whether or not anything else explicitly references the root.

For example, global variables are roots; by referring to an object, a global variable, by definition, makes that object part of the app's live object graph. And, by implication, any objects that the object referred to by the global variable are also considered to be live; not leaked.

The same goes for the stack; any object referred to by any thread's live stack is, itself, considered live.

With this in mind, a leak and abandoned memory actually do have two distinct meanings.

Leak

A leak is a piece of memory for which there are no references to the allocation from any live object in the application's live object graph.

I.e. the memory is unreachable and, thus, there is no way that it can ever be referred to again (barring bugs). It is dead memory.

Note that if object A points to object B and object B points to A, but nothing in the live object graph points to either A or B, it is still a leak. If the B->A and A->B references are both retained references, you got yourself a retain cycle & a leak.

Abandoned Memory

Allocations that are in the app's live object graph but are no longer reachable due to application logic issues are considered abandoned, but not leaked.

For example, say you have a cache whose entries are instances of NSData that were downloaded from some URL where the URL contains a session ID in the URL (a common pattern) and that session ID + URL are used as the key to look up stuff in the cache. Now, say the user logs out, causing the session ID to be destroyed. If the cache isn't also pruned of all entries specific to that session ID, then all of those NSData objects will be abandoned, but not leaked as they can still be reached via the cache.


In reality, there is little use in making this strong of a distinction between the two save for that fixing either requires very different strategies.

Fixing a leak is to figure out where the extra retain came from (or where a missing call to free() might need to be inserted, in the case of a malloc() based leak). Since a detected leak cannot be reached from the live object graph, fixing a leak is really this straightforward.

Fixing abandoned memory can be considerably trickier for a couple of reasons.

First, the memory is still reachable from the live object graph. Thus, by definition, there is an algorithmic problem in your application that is keeping the memory alive. Finding and fixing that can often be much more difficult and potentially disruptive then fixing a mere leak.

Secondly, there might be non-zeroing non-retained weak references to the abandoned allocation. That is, if you figure out where to prune the strong references and make the allocation actually go away, that doesn't mean that your work is done; if there are any remaining non-zeroing weak references, they will now be dangling pointers and..... BOOM.


As Amit indicated, Heapshot Analysis is quite adept at finding both leaks, abandoned memory and -- quite important -- overall "Undesirable Memory Growth".



回答2:

Not sure if there's a standard terminology, but there's also the possibility of having memory around which does have a reference, but will never be used. (The Heap Shot feature of the Leaks instrument can help track this down.) I call this "bloat" to distinguish it from a true leak. Both are wasted memory.



回答3:

Abandoned memory are the memory leaks. Heapshot Analysis will help you to Find Undesirable Memory Growth. This is good article about that. http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/