What's the difference between abandoned memory and a memory leak?
Asked Answered
F

3

13

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

Fugazy answered 12/1, 2012 at 18:18 Comment(4)
They are actually not at all the same thing; leaks can be comprised of whole object graphs quite easily. While the question is posed from a false premise, it is both quite a real question and, imo, an interesting one.Sender
I was about to ask a similar question. With "abandoned memory" you mean unreachable memory, correct?Convincing
Also, how is this related to iOS and objective C?Convincing
Also see here The question and answer tackle this question from a completely different angleSwanky
S
29

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".

Sender answered 12/1, 2012 at 20:54 Comment(5)
Are dangling pointer / abandoned memory / zombie all the same? I know that zombie is an deallocated object. Abandoned memory seems to be different in your jargonSwanky
@Honey Abandoned memory isn't deallocated. The objects are still connected to memory that is actively used by the application, but are no longer useful. Consider; your app does a bunch of calculations and caches the resulting data somewhere-- a global mutable dictionary, perhaps-- then your app loses the key for that cache entry, never to look it up again. That is abandoned memory; the objects exist, consume memory and, possibly, CPU, but they are not useful to your app in any way. A detriment, in fact.Sender
Can you take a look at developer.apple.com/videos/play/wwdc2012/242/?time=1850 I understand the difference of leaks vs abandoned memory. But I think what you described as 'abandoned memory' is what Apple describes as 'cached memory'. Abandoned memory is more of where an object is referenced by a 'root path' e.g. a repeating timer reference by the runloop or a dispatchWorkItem that is referenced by GCD. (1/2)Swanky
Or is that abandoned memory is what I said about root paths + what you said in the sense that the object is no longer accessible to us because we don't have its sessionID, yet still accessible in the live object graph. What Apple was describing as cached memory are objects that you can still reference, but only forget to prune e.g. you can delete images of items that are no longer on the screen(2/2)Swanky
FWIW your example of sessionID, can you just prune everything at the end of the session — without knowing the sessionID? Or is that you've assumed there are things that you'd prefer to keep in the cache even after logout? (3/2)Swanky
D
3

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.

Dishcloth answered 12/1, 2012 at 18:32 Comment(0)
B
1

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/

Boyes answered 12/1, 2012 at 18:36 Comment(1)
Abandoned memories are not leaks. What they both do is make our memory footprint grow for things we no longer need.Swanky

© 2022 - 2024 — McMap. All rights reserved.