Найти утечку памяти в Java-приложении с помощью JeMalloc - PullRequest
0 голосов
/ 06 июня 2018

В настоящее время я пытаюсь решить проблему с памятью Java: мое приложение Java продолжает использовать все больше и больше памяти, и в конечном итоге оно уничтожается убийцей OOM Linux.

Возможно, имеется утечка встроенной памяти, посколькупроверка JVM с помощью VisualVM и метапространства, и кучи выглядят хорошо.

Используя команду top, я вижу, что память, используемая JVM, продолжает увеличиваться.

Первый рисунок в этой статье:

Пример # 1

Идеально соответствует тому, что я вижу в своем собственном приложении.

Поэтому я попытался с помощью JeMalloc найти утечку, как описано в различных статьях.Здесь я сталкиваюсь с проблемой: при использовании команды jeprof, а затем и самой верхней команды в самом jeprof, он показывает функции, которые используют больше всего памяти, но они в шестнадцатеричных адресах, поэтому я должен пропустить некоторые символы.Но я не знаю, какие пакеты мне нужны для этого, что мне неизвестно.

Я уже нашел эту ссылку: Ссылка # 1

И установил этот пакет:debuginfo-install java-1.8.0-openjdk

Сначала я попытался выполнить простые шаги:

Получить JeMalloc для работы с простым приложением, таким как w.Затем заставьте его работать с Java-версией.Пока все хорошо, я также могу получить PDF-файлы от JeMalloc с отличным обзором.

Далее заставьте его работать с java -jar simpletest.jar << Здесь я пропускаю символы Например, если я не закрываюздесь GZipInputStream, который не отображается в результатах JeMalloc. </p>

Далее заставьте его работать с java -jar myapplication.jar << Здесь я также пропускаю символы. </p>

Так что мойВопрос в основном: какие пакеты мне нужны, чтобы JeMalloc отображал все имена символов для отладки приложений, таких как:

public void test1() {
    InputStream fileInputStream = null;
    GZipInputStream gzipInputStream = null;

    try {
      fileInputStream = new FileInputStream("test.zip");
      gzipInputStream = new GZIPInputStream(fileInputStream);

      int data = gzipInputStream.read();
      while (data != -1) {
        // do something with data
        data = gzipInputStream.read();
      }

    } catch (Exception ex) {

    } finally {
      // Disabled to see whether JeMalloc can detect the leak
      /*try {
        if (gzipInputStream != null) {
          gzipInputStream.close();
        }
        if (fileInputStream != null) {
          fileInputStream.close();
        }

        gzipInputStream = null;
        fileInputStream = null;
      } catch (IOException e) {
      e.printStackTrace();
    }*/
  }
}

Использование следующего программного обеспечения:

  • LinuxCentOS 7
  • JeMalloc
  • OpenJDK

Найдено статей:

Артикул 1

Артикул № 2

Артикул № 3

Артикул № 4

1 Ответ

0 голосов
/ 11 октября 2018

Замена распределителя (с jemalloc или tcmalloc для экземпляров) для профилирования использования памяти может дать подсказку об источнике утечки собственной памяти, но она ограничена символами собственного кода, доступными в библиотеках, загруженных в JVM.

Чтобы иметь Javaкласс / метод в трассировке стека, требуется для создания файла отображения, связывающего местоположение памяти собственного кода с его источником.Единственный инструмент на момент написания: https://github.com/jvm-profiling-tools/perf-map-agent

Чтобы получить в стеке больше, чем только имена «интерпретатора», соответствующий код должен быть JIT-скомпилирован, поэтому его применение должно выполняться с -XX:CompileThreshold=1 в параметрах командной строки JVMинтересно (за исключением производственного IMO).

Когда агент загружен в JVM, сгенерирован файл сопоставления и скомпилирован код JIT, perf может использоваться для сообщения о профилировании процессора.Исследование утечки памяти требует дополнительной обработки.

Лучший вариант - получить bcc и его инструмент memleak, если ядро ​​Linux имеет версию 4.9 или выше: https://github.com/iovisor/bcc/blob/master/tools/memleak_example.txt

Большое спасибо Брендан Грегг

Система Debian готовится после простого apt install bcc, но система RedHat требует больше работы, как описано для CentOS 7 в http://hydandata.org/installing-ebpf-tools-bcc-and-ply-on-centos-7 (это еще хуже в CentOS 6)

В качестве альтернативы perf может также сообщать только трассировку стека утечки с определенными датчиками.Сценарии и примеры использования доступны по адресу https://github.com/dkogan/memory_leak_instrumentation, но должны быть адаптированы к контексту Java.

...