Как отладить утечку памяти, когда экземпляры исключений в дампе кучи не имеют входящих ссылок? - PullRequest
6 голосов
/ 03 сентября 2010

Я пытался диагностировать утечку памяти в приложении для Android, которое я пишу.Я загрузил дамп кучи в Eclipse, но результаты, которые я вижу, очень любопытны.Существует около 20 000 экземпляров исключения (в частности, LDAPException из библиотеки UnboundID LDAP) в куче без входящих ссылок.

То есть они отображаются в корне дерева доминирования.OQL SELECT objects e FROM com.unboundid.ldap.sdk.LDAPException e WHERE (inbounds(e).length = 0) возвращает более 20 000 результатов, что составляет почти всю кучу.И все же GC запускается перед дампом кучи, и я вижу, что он неоднократно запускается в консоли во время выполнения кода с утечкой.Если эти экземпляры не имеют входящих ссылок, что может их поддерживать?

Я также попытался выполнить запрос "кратчайшие пути к ГХ".Он показывает одну строку LDAPConnectionReader, сохраняющую 2 экземпляра, и ~ 20k LDAPException @ <addr> unknown строк с различными шестнадцатеричными адресами.

Обновление : у меня не было времени для дальнейшей диагностики этого с момента публикации,щедрость, которую я отправил, заканчивается прежде, чем я, вероятно, буду.Я награждаю его как можно лучше, чтобы очки не пропали даром.Спасибо всем, кто заглянул в это!Я вернусь позже и обновлю результаты дальнейшего диагноза, когда жизнь станет немного менее беспокойной.

Ответы [ 3 ]

4 голосов
/ 10 сентября 2010

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

Хотя вы хотели бы видеть в дампе кучи, кто хранит ссылки, по какой-то причине вы не можете добраться до этого. Интересно, будет ли собственный код правильно обозначен в инструменте дампа кучи?

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

1 голос
/ 11 сентября 2010

Я не знаком с OQL, или с платформой Android в частности, или с внутренней работой Java GC на этой платформе, но наиболее очевидным для меня является отсутствие метаданных LDAPException.У него есть коды ошибок, сообщения, методы и т.д ... где это?это было неинициализировано?Вам запрещено публиковать все эти вещи?Что-то , например сервер, перенаправляющий на себя , может заставить меня сказать: «О, это странно, но это имеет смысл».

Вы пытались заменить эту библиотеку на JDK ?Похоже, это должно быть легко, если это возможно.

Тогда я бы начал сжимать кучу всего, что у него есть.Характеристики ГХ могут дать подсказки.Существуют ли экземпляры, которые каким-то образом избегают сбора?Сколько создается в секунду?Какую долю устаревших gc'd каждый проход, или это постоянное количество?Они создаются в напряженном цикле, о котором говорил Дэнни?Что если вы позвоните System.gc() в занятом цикле?

Но да, вот где я начинаю отладку печати.Надеюсь, есть лучшее решение.:-P

1 голос
/ 10 сентября 2010

Если вы используете Eclipse, вы можете добавить точку останова на LDAPException.Здесь вы можете найти учебное пособие о том, как его установить: Eclipse Совет: точка останова на исключении .

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

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

...