В чем разница между оставленной памятью и утечкой памяти? - PullRequest
12 голосов
/ 12 января 2012

И то, и другое - одно и то же, за исключением того, что «заброшенная память» относится к утечке всего графа объектов, а не к одному объекту.Правильно?

Ответы [ 3 ]

27 голосов
/ 13 января 2012

Во-первых, вам необходимо понять понятие «граф объекта памяти» или «граф объекта приложения» (или просто «граф объекта» в применении к выделенным буферам). В этом случае «объект» относится к любому выделению в вашем приложении, будь то объект или простой malloc() ed-буфер. Часть «граф», если любой объект может содержать ссылку на указатель на другие объекты.

«График живых объектов» приложения - это все распределения, которые могут быть получены прямо или косвенно из различных «корней» приложения. «Корень» - это то, что само по себе представляет живую ссылку на объект, независимо от того, ссылается ли что-либо явно на корень или нет.

Например, глобальные переменные являются корнями; ссылаясь на объект, глобальная переменная по определению делает этот объект частью графа живых объектов приложения . И, косвенно, любые объекты, которые объект, на который ссылается глобальная переменная, также считаются живыми; не просочилась.

То же самое относится и к стеку; любой объект, на который ссылается живой стек любого потока, сам по себе считается живым.

Имея это в виду, утечка и заброшенная память на самом деле имеют два разных значения.

Leak

Утечка - это часть памяти, для которой нет ссылок на выделение из любого живого объекта в графе живого объекта приложения .

т.е. память недоступна, и, таким образом, нет способа, чтобы на нее можно было снова сослаться (исключая ошибки). Это мертвая память.

Обратите внимание, что если объект A указывает на объект B, а объект B указывает на A, но ничто в графе живого объекта не указывает ни на A, ни на B, это все равно утечка. Если ссылки B-> A и A-> B являются сохраненными ссылками, вы получили себе цикл сохранения и утечку.

Заброшенная память

Распределения, которые находятся в графике живых объектов приложения , но более недоступны из-за проблем логики приложения, считаются заброшенными, но не просочившимися.

Например, допустим, у вас есть кэш, записи которого являются экземплярами NSData, которые были загружены с некоторого URL, где URL содержит идентификатор сеанса в URL (общий шаблон), и этот идентификатор сеанса + URL используются в качестве ключ для поиска вещей в кеше. Теперь, скажем, пользователь выходит из системы, вызывая уничтожение идентификатора сеанса. Если кэш также не очищен от всех записей, относящихся к этому идентификатору сеанса, то все эти NSData объекты будут заброшены, но не утекут, так как они все еще могут быть достигнуты через кеш.

<Ч />

На самом деле мало что делает для того, чтобы провести такое сильное различие между двумя вариантами, кроме того, что для исправления требуется либо совсем другая стратегия.

Устранить утечку, чтобы выяснить, откуда пришло дополнительное удержание (или где может потребоваться вставить отсутствующий вызов на free(), в случае утечки на основе malloc()). Поскольку обнаруженная утечка не может быть достигнута из графика живых объектов, устранить утечку действительно так просто.

Исправление оставленной памяти может быть значительно сложнее по нескольким причинам.

Во-первых, память все еще доступна из графа живых объектов. Таким образом, по определению, в вашем приложении есть алгоритмическая проблема, которая поддерживает память активной. Поиск и исправление, которые зачастую могут быть гораздо более сложными и потенциально разрушительными, чем устранение простой утечки.

Во-вторых, могут быть ненулевые необеспеченные слабые ссылки на отмененное распределение. То есть, если вы выясняете, где следует удалить сильные ссылки и фактически прекратить распределение, это не означает, что ваша работа выполнена; если остаются какие-либо ненулевые слабые ссылки, они теперь будут висящими указателями и ..... BOOM .

<Ч />

Как указал Амит, Анализ хип-снимков весьма искусен в обнаружении утечек, оставленной памяти и - что очень важно - общего "нежелательного роста памяти".

3 голосов
/ 12 января 2012

Не уверен, что существует стандартная терминология, но есть также возможность иметь память, вокруг которой есть ссылка, но она никогда не будет использоваться. (Функция Heap Shot инструмента Leaks может помочь отследить это.) Я называю это «раздуванием», чтобы отличить его от настоящей утечки. Оба потрачены впустую памяти.

1 голос
/ 12 января 2012

Оставленная память - это утечки памяти.Анализ Heapshot поможет вам найти нежелательный рост памяти.Это хорошая статья об этом.http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...