2015-06-19 4 views
2

Мой кусок кучи Java-приложений показывает, что определенная лямбда, используемая в моем классе, заблокировала некоторый объем памяти и не освобождается во время GC.Анализ дампа Java-кучи для лямбда-выражений

Куча показывает конкретную анонимную категорию лямбда как ParentClass $$ Lambda $ ID и в этом случае идентификатор 79 (изображение прилагается). Этот идентификатор, по-видимому, не имеет никакого отношения к числу лямбда, которые существуют в классе, и поэтому мы не можем заключить, на каком лямбда представлено. Мне интересно указать точное выражение лямбда, поскольку оно помогает в анализе, исправлении и тестировании связанных с ним сценариев.

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

enter image description here

+2

Если выражение лямбда выделяет значительный объем памяти, в нем должны быть зафиксированы значения. Таким образом, проверка экземпляра (ов) может привести вас к информации, которая является фактическим выражением лямбда. Далее вы можете профилировать * allocations *, чтобы найти источник ... – Holger

+0

@ Хольджер Здесь я должен быть более точным. Этот класс имеет множественные лямбды, предназначенные для разных целей подобного рода. Я опишу простым языком - скажем, у меня есть методы getAccountName, getAccountBalance, getAccountNominee и т. Д. - предположим, что каждый из них совершает вызовы на веб-сервисы на разных серверах, а ответы будут возвращены другим методам обработки без сохранения состояния. Проблема заключается в том, что одна из служб занимает бесконечное время, а служба и мое приложение не имеют тайм-аута, который сохраняет «DefaultHttpClient» (строка) как живой объект. Так что нет способа определить, какая лямбда. –

+2

Кроме того, глядя на его свойства (полученные значения и аргументы) в виде исходящих ссылок, вы также можете посмотреть на входящие ссылки, т. Е. Вещи, которые держатся за лямбда. обычно должно быть достаточно, чтобы найти его в – the8472

ответ

4

Попробуйте определение системного свойства

jdk.internal.lambda.dumpProxyClasses=/path/to/dir 

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

+1

На нем не так много документации, кроме https://bugs.openjdk.java.net/browse/JDK-8023524 - хотя это может и не быть решением для JDK. Я попробую и дам вам знать. –

+0

Хорошее решение, надеюсь, что нечто подобное (не специфическое для jvm) существует аналогичным образом. –

+1

@Pavan Kumar: поскольку все существование этих классов специфично для JVM, не может быть опция сбрасывать их, которые не являются JVM-специфическими ... – Holger

Смежные вопросы