废弃的内存和内存泄漏之间有什么区别? [英] What's the difference between abandoned memory and a memory leak?

查看:252
本文介绍了废弃的内存和内存泄漏之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两者完全相同,只是废弃的内存"是指泄漏的整个对象图,而不是单个对象.对吧?

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

推荐答案

首先,您需要了解内存对象图"或应用程序对象图"(或简称为对象图")的概念到分配的缓冲区).在这种情况下,对象"是指应用程序中的任何分配,无论是对象还是简单的malloc() ed缓冲区. 图形"部分是指任何对象都可以包含对其他对象的引用-指针.

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.

泄漏是一块内存,对于它来说,没有引用来自应用程序活动对象图中任何活动对象的分配.

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.

请注意,如果对象A指向对象B,而对象B指向A,但是活动对象图中没有任何东西指向A或B,则仍然是泄漏.如果B-> A和A-> B引用都是保留引用,则您将获得一个保留周期&.泄漏.

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.

应用程序的活动对象图中中的分配但由于应用程序逻辑问题而无法访问的分配被视为放弃,但不会泄漏.

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.

例如,假设您有一个缓存,该缓存的条目是NSData的实例,这些实例是从某个URL下载的,其中该URL包含URL中的会话ID(一种常见模式),并且该会话ID + URL被用作在缓存中查找内容的关键.现在,假设用户注销,从而导致会话ID被破坏.如果还没有删除特定于该会话ID的所有条目的缓存,则所有这些NSData对象都将被放弃,但不会泄漏,因为仍然可以通过缓存访问它们.

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.

修复泄漏是为了找出额外的保留来自何处(或者在基于malloc()的泄漏情况下,可能需要插入对free()的丢失的调用).由于无法从活动对象图中达到检测到的泄漏 ,因此解决泄漏确实非常简单.

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.

首先,可以从活动对象图中 still 访问内存.因此,根据定义,您的应用程序中存在一个算法问题,该问题使内存保持活动状态.与仅修复泄漏相比,查找和修复通常要困难得多且可能具有破坏性.

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.

第二,可能存在对废弃分配的非归零非保留弱引用.就是说,如果您想出哪些地方可以删除强引用,并使分配实际上消失了,那并不意味着您的工作已经完成;如果有任何剩余的非归零弱引用,它们现在将悬空指针和..... BOOM .

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.

正如阿米特(Amit)指出的,

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

这篇关于废弃的内存和内存泄漏之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆