Чи є спосіб побачити власний код, який виробляє JIT, у JVM?
Чи є спосіб побачити власний код, який виробляє JIT, у JVM?
Відповіді:
Припускаючи, що ви використовуєте Sun Hotspot JVM (тобто той, який надає Oracle на java.com ), ви можете додати прапор
-XX: + PrintOptoAssembly
під час запуску коду. Це роздрукує оптимізований код, створений компілятором JIT, а решту залишить.
Якщо ви хочете побачити весь байт-код, включаючи неоптимізовані частини, додайте
-XX: CompileThreshold = #
коли ви запускаєте свій код.
Детальніше про цю команду та функціональність JIT ви можете прочитати тут .
Як пояснюється іншими відповідями, ви можете запустити такі опції JVM:
-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
Ви також можете відфільтрувати певний метод із таким синтаксисом:
-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*MyClass.myMethod
Примітки:
Якщо у вас 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
Встановіть 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, hsdis makefile не розпізнає його як такий.
./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 перед AT&T, вкажіть -XX:PrintAssemblyOptions=intel
поряд із будь-якими іншими параметрами PrintAssembly, які ви використовуєте.
* ліцензія на сторінку - Creative Commons
/usr/lib/
Вам потрібен плагін hsdis для використання PrintAssembly
. Зручним вибором є плагін hsdis на основі бібліотеки FCML.
Його можна скомпілювати для UNIX-подібних систем, а в Windows ви можете використовувати попередньо вбудовані бібліотеки, доступні в розділі завантаження FCML на Sourceforge:
java.dll
(використовуйте пошук Windows). У своїй системі я знайшов його в двох місцях:
C:\Program Files\Java\jre1.8.0_45\bin\server
C:\Program Files\Java\jdk1.8.0_45\jre\bin\server
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
Додаткові параметри конфігурації:
код Друк машинного коду перед мнемонікою.
intel Використовуйте синтаксис Intel.
газ Використовуйте синтаксис асемблера AT&T (сумісний з асемблером GNU).
dec Друкує IMM та переміщення як десяткові значення.
mpad = XX Заповнення мнемонічної частини інструкції.
cpad = XX Заповнення машинного коду.
seg Показує регістри сегментів за замовчуванням.
нулі Показати провідні нулі для літералів HEX.
Синтаксис Intel є типовим для Windows, тоді як AT&T є типовим для GNU / Linux.
Докладніше див. У довідковому посібнику бібліотеки FCML
apt-get install libhsdis0-fcml
( askubuntu.com/a/991166/489909 ). Будувати це самостійно може не знадобитися.
Для HotSpot (було Sun) JVM, навіть у режимах продукту:
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.
Надрукуйте збірку своїх гарячих точок за допомогою профілів для парфуму JMH ( LinuxPerfAsmProfiler
або WinPerfAsmProfiler
). JMH вимагає hsdis
бібліотеки, оскільки вона покладається на PrintAssembly
.