Вы уверены, что хотите увидеть JIT-скомпилированный (собственный) код или просто байт-код? Я спрашиваю, потому что этот вопрос вызывает некоторые сомнения, действительно ли вы хотите увидеть собственный код ... И, извините, я тоже не знаю такого инструмента.
gimpf 01
3
Я хочу видеть точный JIT-скомпилированный собственный код. Конечно, это не то, что мне нужно для выполнения работы, это скорее эксперименты и исследования.
alsor.net 01
Незначительная проблема с кадрами: динамический компилятор, используемый в современных JVM, не имеет только одной версии скомпилированного кода; он может начать с интерпретации, затем скомпилировать метод или его часть, а затем потенциально перекомпилировать его несколько раз по мере загрузки / выгрузки классов или изменения шаблонов использования или на основе статистики производительности. (Я думаю, что он может даже отказаться от скомпилированной версии и вернуться к интерпретации, если это покажется полезным.) Таким образом, вы можете получить не только разный код на разных машинах и даже для разных запусков на одной машине, но и в разное время в одном и том же запуске. .
gidds
Ответы:
45
Предполагая, что вы используете JVM Sun Hotspot (то есть ту, которая предоставляется Oracle на java.com ), вы можете добавить флаг
-XX: + PrintOptoAssembly
при запуске вашего кода. Это распечатает оптимизированный код, сгенерированный JIT-компилятором, и оставит все остальное.
Если вы хотите увидеть весь байт-код, включая неоптимизированные части, добавьте
-XX: CompileThreshold = #
когда вы запускаете свой код.
Вы можете узнать больше об этой команде и о функциональных возможностях JIT в целом здесь .
Эта опция присутствует только в отладочных сборках или в чем-то еще? Потому что моя JVM ("Java (TM) SE Runtime Environment (build 1.6.0_16-b01") не распознает ее, хотя исходный текст в Интернете указывает, что эта функция доступна в Sun Java 6 и OpenJDK.
Разве это не должно быть (сейчас) -XX: + PrintAssembly, по крайней мере, в наши дни? Протестировано на моей машине и соответствует тому, что здесь сказано: wikis.sun.com/display/HotSpotInternals/PrintAssembly. Вам нужно -XX: + UnlockDiagnosticVMOptions перед этой опцией и плагином дизассемблера.
Blaisorblade
@Blaisorblade Я получаю: Неправильно указанный параметр виртуальной машины «PrintAssembly». Ошибка: не удалось создать виртуальную машину Java. Ошибка: возникла фатальная исключительная ситуация. Программа будет закрыта.
вам может потребоваться заключить второй аргумент в кавычки в зависимости от ОС и т. д.
если метод будет встроен, вы можете пропустить некоторые оптимизации
Как: установить необходимые библиотеки в Windows
Если вы используете Windows, на этой странице есть инструкции по сборке и установке, hsdis-amd64.dllа также о том, hsdis-i386.dllчто необходимо для ее работы. Мы копируем ниже и расширяем содержание этой страницы * для справки:
Где взять готовые двоичные файлы
Вы можете скачать готовые двоичные файлы для Windows из проекта fcml
Как собрать hsdis-amd64.dllи hsdis-i386.dllна Windows
Эта версия руководства была подготовлена для 64-разрядной версии Windows 8.1 с использованием 64-разрядной версии Cygwin и создания hsdis-amd64.dll.
Установите Cygwin . На Select Packagesэкране добавьте следующие пакеты (развернув Develкатегорию, а затем один раз щелкнув Skipярлык рядом с названием каждого пакета):
make
mingw64-x86_64-gcc-core(требуется только для hsdis-amd64.dll)
mingw64-i686-gcc-core(требуется только для hsdis-i386.dll)
diffutils(в Utilsкатегории)
Запустите терминал Cygwin. Это можно сделать с помощью значка на рабочем столе или в меню «Пуск», созданного установщиком, который создаст ваш домашний каталог Cygwin ( C:\cygwin\home\<username>\или C:\cygwin64\home\<username>\по умолчанию).
Загрузите последний пакет исходного кода GNU binutils и извлеките его содержимое в домашний каталог Cygwin. На момент написания последней версии пакета является binutils-2.25.tar.bz2. Это должно привести к созданию каталога с именем binutils-2.25(или любой другой последней версии) в вашем домашнем каталоге Cygwin.
Загрузите исходный код OpenJDK, перейдя в репозиторий обновлений JDK 8 , выбрав тег, соответствующий вашей установленной версии JRE, и щелкнув bz2. Извлеките каталог hsdis (находится в src\share\tools) в домашний каталог Cygwin.
В терминале Cygwin введите cd ~/hsdis.
Чтобы построить 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-подобной средой, make-файл hsdis не может распознать ее как таковую.
Сборка завершится ошибкой с сообщениями ./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в каталог JRE bin\serverили bin\client. Вы можете найти все такие каталоги в своей системе, выполнив поиск java.dll.
Дополнительный совет: если вы предпочитаете синтаксис Intel ASM -XX:PrintAssemblyOptions=intelвместо AT&T, укажите вместе с любыми другими используемыми вами параметрами PrintAssembly.
@AshwinJayaprakash Куда мне поместить эти файлы в Mac OS?
Корай Тугай
@KorayTugay вставил их/usr/lib/
Жан-Франсуа Савар
Я обновил ответ, скопировав из последней версии связанной страницы, но это подчеркивает причину, по которой мы обычно ссылаемся на внешние ресурсы, а не копируем их дословно.
Александр Дубинский
@AleksandrDubinsky Спасибо за обновление. Я скопировал его специально: если этот сайт выйдет из
строя,
29
Для использования вам понадобится плагин hsdis PrintAssembly. Удобный выбор - плагин hsdis на основе библиотеки FCML.
Его можно скомпилировать для UNIX-подобных систем, а в Windows вы можете использовать готовые библиотеки, доступные в разделе загрузки FCML на Sourceforge:
Для установки в Windows:
Распакуйте dll (ее можно найти в hsdis-1.1.2-win32-i386.zip и hsdis-1.1.2-win32-amd64.zip).
Скопируйте dll туда, где есть java.dll(используйте поиск Windows). В своей системе я нашел его в двух местах:
code Вывести машинный код перед мнемоникой. intel Используйте синтаксис Intel. gas Используйте синтаксис ассемблера AT&T (совместимый с GNU ассемблер). dec Печатает IMM и смещение как десятичные значения. mpad = XX Заполнение мнемонической части инструкции. cpad = XX Заполнение машинного кода. seg Показывает регистры сегментов по умолчанию. нули Показывать ведущие нули в случае шестнадцатеричных литералов.
Синтаксис Intel является синтаксисом по умолчанию в случае Windows, тогда как синтаксис AT&T используется по умолчанию для GNU / Linux.
Спасибо за исправление библиотеки. Он также отлично работает в Linux. Я удаляю свои старые комментарии, чтобы не было беспорядка.
Александр Дубинский
В Linux после того, как я установил libhsdis.so и сделал программную ссылку на hsdis-amd64.so, я запускаю команду java, она не может найти hsdis-amd64.so. Я перезагружаюсь, а затем повторно запускаю java, все в порядке. Как избежать перезагрузки, чтобы софт линк заработал мгновенно? выйти?
gfan
2
Небольшое дополнение: в некоторых дистрибутивах Linux вы можете просто установить пакет, например, в Ubuntu: apt-get install libhsdis0-fcml( askubuntu.com/a/991166/489909 ). Самостоятельное создание этого может не потребоваться.
Дэвид Георг Райхельт
8
Для JVM HotSpot (было Sun) даже в режимах продукта:
Выделенные строки - это прямой запуск JIT-кода на JVM.
Затем мы можем найти адрес метода: 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-код из дампов памяти с помощью проводника процессов и WinDbg.
Другой способ увидеть машинный код и некоторые данные о производительности - использовать AMD CodeAnalyst или OProfile, в которых есть подключаемый модуль Java для визуализации выполнения кода Java как машинного кода.
Распечатайте сборку ваших горячих точек с помощью профилировщика JMH perfasm ( LinuxPerfAsmProfilerили WinPerfAsmProfiler). JMH действительно требует hsdisбиблиотеки, поскольку он полагается на PrintAssembly.
Ответы:
Предполагая, что вы используете JVM Sun Hotspot (то есть ту, которая предоставляется Oracle на java.com ), вы можете добавить флаг
при запуске вашего кода. Это распечатает оптимизированный код, сгенерированный JIT-компилятором, и оставит все остальное.
Если вы хотите увидеть весь байт-код, включая неоптимизированные части, добавьте
когда вы запускаете свой код.
Вы можете узнать больше об этой команде и о функциональных возможностях JIT в целом здесь .
источник
Общее использование
Как объясняется в других ответах, вы можете работать со следующими параметрами JVM:
Фильтр по определенному методу
Вы также можете отфильтровать определенный метод с помощью следующего синтаксиса:
Ноты:
Как: установить необходимые библиотеки в Windows
Если вы используете Windows, на этой странице есть инструкции по сборке и установке,
hsdis-amd64.dll
а также о том,hsdis-i386.dll
что необходимо для ее работы. Мы копируем ниже и расширяем содержание этой страницы * для справки:Где взять готовые двоичные файлы
Вы можете скачать готовые двоичные файлы для Windows из проекта fcml
Как собрать
hsdis-amd64.dll
иhsdis-i386.dll
на WindowsЭта версия руководства была подготовлена для 64-разрядной версии Windows 8.1 с использованием 64-разрядной версии Cygwin и создания hsdis-amd64.dll.
Установите Cygwin . На
Select Packages
экране добавьте следующие пакеты (развернувDevel
категорию, а затем один раз щелкнувSkip
ярлык рядом с названием каждого пакета):make
mingw64-x86_64-gcc-core
(требуется только дляhsdis-amd64.dll
)mingw64-i686-gcc-core
(требуется только дляhsdis-i386.dll
)diffutils
(вUtils
категории)Запустите терминал Cygwin. Это можно сделать с помощью значка на рабочем столе или в меню «Пуск», созданного установщиком, который создаст ваш домашний каталог Cygwin (
C:\cygwin\home\<username>\
илиC:\cygwin64\home\<username>\
по умолчанию).binutils-2.25.tar.bz2
. Это должно привести к созданию каталога с именемbinutils-2.25
(или любой другой последней версии) в вашем домашнем каталоге Cygwin.src\share\tools
) в домашний каталог Cygwin.cd ~/hsdis
.Чтобы построить
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-подобной средой, make-файл hsdis не может распознать ее как таковую../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
в каталог JREbin\server
илиbin\client
. Вы можете найти все такие каталоги в своей системе, выполнив поискjava.dll
.Дополнительный совет: если вы предпочитаете синтаксис Intel ASM
-XX:PrintAssemblyOptions=intel
вместо AT&T, укажите вместе с любыми другими используемыми вами параметрами PrintAssembly.* лицензия на страницу - Creative Commons
источник
/usr/lib/
Для использования вам понадобится плагин hsdis
PrintAssembly
. Удобный выбор - плагин hsdis на основе библиотеки FCML.Его можно скомпилировать для UNIX-подобных систем, а в Windows вы можете использовать готовые библиотеки, доступные в разделе загрузки FCML на Sourceforge:
Для установки в Windows:
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
/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
Дополнительные параметры конфигурации:
code Вывести машинный код перед мнемоникой.
intel Используйте синтаксис Intel.
gas Используйте синтаксис ассемблера AT&T (совместимый с GNU ассемблер).
dec Печатает IMM и смещение как десятичные значения.
mpad = XX Заполнение мнемонической части инструкции.
cpad = XX Заполнение машинного кода.
seg Показывает регистры сегментов по умолчанию.
нули Показывать ведущие нули в случае шестнадцатеричных литералов.
Синтаксис Intel является синтаксисом по умолчанию в случае Windows, тогда как синтаксис AT&T используется по умолчанию для GNU / Linux.
Дополнительные сведения см. В Справочном руководстве по библиотеке FCML.
источник
apt-get install libhsdis0-fcml
( askubuntu.com/a/991166/489909 ). Самостоятельное создание этого может не потребоваться.Для JVM HotSpot (было Sun) даже в режимах продукта:
http://wikis.oracle.com/display/HotSpotInternals/PrintAssembly
Требуется некоторая сборка: нужен плагин.
источник
Я считаю, что WinDbg будет полезен, если вы используете его на машине с Windows. Я только что запустил одну банку.
Просмотрел неуправляемый стек вызовов по kb там было:
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-кода на JVM.
Затем мы можем найти адрес метода:
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-код из дампов памяти с помощью проводника процессов и WinDbg.
источник
Другой способ увидеть машинный код и некоторые данные о производительности - использовать AMD CodeAnalyst или OProfile, в которых есть подключаемый модуль Java для визуализации выполнения кода Java как машинного кода.
источник
Распечатайте сборку ваших горячих точек с помощью профилировщика JMH perfasm (
LinuxPerfAsmProfiler
илиWinPerfAsmProfiler
). JMH действительно требуетhsdis
библиотеки, поскольку он полагается наPrintAssembly
.источник