Как увидеть JIT-скомпилированный код в JVM?



есть ли способ увидеть собственный код, создаваемый JIT в JVM?

607   7  

7 ответов:

предполагая, что вы используете Sun Hotspot JVM (т. е. тот, который предоставляется на java.com от Oracle), вы можете добавить флаг

- XX: + PrintOptoAssembly

при выполнении кода. Это выведет оптимизированный код, сгенерированный JIT-компилятором,и оставит все остальное.

Если вы хотите увидеть весь байт-код, включая неоптимизированные части, добавьте

- XX: CompileThreshold=#

когда вы запускаете свой код.

вы можете прочитать больше об этой команде и функциональности JIT в целом здесь.

общего пользования

как объясняется другими ответами, вы можете работать со следующими параметрами JVM:

-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly

фильтр по определенному методу

вы также можете фильтровать по определенному методу со следующим синтаксисом:

-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*MyClass.myMethod

Примечания:

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

Как установить необходимые библиотеки в Windows

если вы используете Windows,на этой странице имеет инструкции о том, как построить и установить hsdis-amd64.dll и hsdis-i386.dll, которые требуются, чтобы заставить его работать. Мы копируем ниже и расширяем содержание этой страницы* для справки:


где получить готовые двоичные файлы

вы можете скачать готовые двоичные файлы для Windows из fcml проект

как построить hsdis-amd64.dll и hsdis-i386.dll на Windows

эта версия руководства была подготовлена на Windows 8.1 64bit с использованием 64-разрядного Cygwin и производства hsdis-amd64.dll

  1. Установить Cygwin. На Select Packages экран, добавьте следующие пакеты (путем расширения Devel категория, затем нажмите один раз на Skip метка рядом с именем каждого пакета):

    • make
    • mingw64-x86_64-gcc-core (требуется только для hsdis-amd64.dll)
    • mingw64-i686-gcc-core (требуется только для hsdis-i386.dll)
    • diffutils (in )
  2. запустите терминал Cygwin. Это можно сделать с помощью значка рабочего стола или меню Пуск, созданного установщиком, и создаст ваш Cygwin домашний каталог (C:\cygwin\home\<username>\ или C:\cygwin64\home\<username>\ по умолчанию).

  3. загрузите последний исходный пакет GNU binutils и извлеките его содержимое в свой домашний каталог Cygwin. На момент написания статьи, последний пакет binutils-2.25.tar.bz2. Это должно привести к каталогу с именем binutils-2.25 (или независимо от последней версии) в вашем домашнем каталоге Cygwin.
  4. загрузите исходный код OpenJDK с помощью переход в репозиторий обновлений JDK 8 выбор тег, соответствующий установленной версии JRE, и нажмите кнопку bz2. Извлеките каталог hsdis (находится в src\share\tools) в ваш домашний каталог Cygwin.
  5. в терминале Cygwin введите cd ~/hsdis.
  6. построить hsdis-amd64.dll введите

    make OS=Linux MINGW=x86_64-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25

    построить hsdis-i386.dll введите

    make OS=Linux MINGW=i686-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25

    в любом случае, заменить 2.25 с версией binutils, которую вы загрузили. OS=Linux необходимо, потому что, хотя Cygwin-это Linux-подобная среда, hsdis makefile не распознает ее как таковую.

  7. сборка завершится ошибкой с сообщением ./chew: No such file or directory и gcc: command not found. Редактировать <Cygwin home directory>\hsdis\build\Linux-amd64\bfd\Makefile в текстовом редакторе, таком как Wordpad или Notepad++, чтобы изменить SUBDIRS = doc po (строка 342, если используется binutils 2.25) до SUBDIRS = po. Повторите выполнение предыдущей команды.

DLL теперь можно установить, скопировав его из hsdis\build\Linux-amd64 или hsdis\build\Linux-i586 к или . Вы можете найти все такие каталоги в вашей системе путем поиска java.dll.

бонусный совет: если вы предпочитаете синтаксис Intel ASM для AT&T, укажите -XX:PrintAssemblyOptions=intel наряду с любыми другими опциями PrintAssembly вы используете.

*лицензия на страницу Creative Commons

вам нужен плагин hsdis для использования PrintAssembly. Удобным выбором является плагин hsdis на основе библиотеки FCML.

он может быть скомпилирован для UNIX-подобных систем, а в Windows вы можете использовать готовые библиотеки, доступные в FCML скачать раздел на Sourceforge:

для установки в Windows:

  • извлечь dll (его можно найти в hsdis-1.1.2-win32-i386.zip и hsdis-1.1.2-win32-amd64.промелькнуть.)
  • скопируйте dll в там, где существует java.dll (используйте поиск Windows). В моей системе я нашел его в двух местах:
    • C:\Program Files\Java\jre1.8.0_45\bin\server
    • C:\Program Files\Java\jdk1.8.0_45\jre\bin\server

для установки в Linux:

  • скачать исходный код, распакуйте его
  • cd <source code dir>
  • ./configure && make && sudo make install
  • cd example/hsdis && make && sudo make install
  • sudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/lib/amd64/hsdis-amd64.so
  • sudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/jre/lib/amd64/hsdis-amd64.so
  • в моей системе JDK находится в /usr/lib/jvm/java-8-oracle

как запустить его:

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly 
-XX:+LogCompilation -XX:PrintAssemblyOptions=intel,mpad=10,cpad=10,code 
-jar fcml-test.jar

Дополнительные параметры конфигурации:

код печать машинного кода перед мнемоническим.
intel используйте синтаксис Intel.
газ используйте синтаксис ассемблера AT&T (совместимый с ассемблером GNU).
dec выводит IMM и смещение в виде десятичных значений.
mpad=XX дополнение для мнемонической части инструкция.
cpad=XX дополнение для машинного кода.
seg показывает регистры сегментов по умолчанию.
нули показать ведущие нули в случае шестнадцатеричных литералов.

синтаксис Intel является синтаксисом по умолчанию в случае Windows, тогда как AT&T является синтаксисом по умолчанию для GNU/Linux.

для получения более подробной информации см. справочник по библиотеке FCML

для Точки доступа (было солнце) JVM, даже в режимах продукта:

http://wikis.oracle.com/display/HotSpotInternals/PrintAssembly

требуется некоторая сборка: ей нужен плагин.

Я считаю, что WinDbg было бы полезно, если вы используете его на машине windows. Я только что запустил одну банку.

  • затем я подключился к процессу java через Windbg
  • исследовал потоки по ~ команда; было 11 потоков, 0 поток был основной рабочий поток
  • переключился на 0-поток - ~0s
  • просмотрел неуправляемый callstack by КБ там было:

    0008fba8 7c90e9c0 ntdll!KiFastSystemCallRet
    0008fbac 7c8025cb ntdll!ZwWaitForSingleObject+0xc
    0008fc10 7c802532 kernel32!WaitForSingleObjectEx+0xa8
    0008fc24 00403a13 kernel32!WaitForSingleObject+0x12
    0008fc40 00402f68 java+0x3a13
    0008fee4 004087b8 java+0x2f68
    0008ffc0 7c816fd7 java+0x87b8

    0008fff0 00000000 kernel32!BaseProcessStart+0x23

выделены линии прямой выполняется с помощью JIT-Эд-код на виртуальной машине.

  • тогда мы можем искать адрес метода:
    java+0x2f68-это 00402f68

  • На WinDBG:
    Выберите Вид --> Разборка.
    нажмите Изменить -- > перейти Адрес.
    поставить 00402f68 здесь
    и получил

    00402f68 55 push ebp
    00402f69 8bec mov ebp, esp
    00402f6b 81ec80020000 sub esp, 280h
    00402f71 53 push ebx
    00402f72 56 push esi
    00402f73 57 push edi
    ... и так далее

для дополнительной информации вот пример как отследить JIT-ed код из дампов памяти с помощью Process explorer и WinDbg.

еще один способ увидеть машинный код и некоторые данные о производительности-использовать AMD CodeAnalyst или OProfile, которые имеют плагин Java для визуализации выполнения кода Java как машинного кода.

печать сборки ваших горячих точек с помощью профилировщиков perfasm JMH (LinuxPerfAsmProfiler или WinPerfAsmProfiler). JMH действительно требует hsdis библиотека, так как она опирается на PrintAssembly.

Comments

    Ничего не найдено.