Czy istnieje sposób, aby zobaczyć natywny kod generowany przez JIT w JVM?
Czy istnieje sposób, aby zobaczyć natywny kod generowany przez JIT w JVM?
Odpowiedzi:
Zakładając, że używasz maszyny wirtualnej Sun Hotspot JVM (tj. Tej dostarczonej na java.com przez Oracle), możesz dodać flagę
-XX: + PrintOptoAssembly
podczas uruchamiania kodu. Spowoduje to wydrukowanie zoptymalizowanego kodu wygenerowanego przez kompilator JIT i pominie resztę.
Jeśli chcesz zobaczyć cały kod bajtowy, w tym niezoptymalizowane części, dodaj
-XX: CompileThreshold = #
kiedy uruchamiasz swój kod.
Możesz przeczytać więcej o tym poleceniu i ogólnie o funkcjonalności JIT tutaj .
Jak wyjaśniono w innych odpowiedziach, możesz uruchomić z następującymi opcjami JVM:
-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
Możesz również filtrować według określonej metody za pomocą następującej składni:
-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*MyClass.myMethod
Uwagi:
Jeśli używasz systemu Windows, na tej stronie znajdują się instrukcje, jak zbudować i zainstalować hsdis-amd64.dlloraz hsdis-i386.dllco jest wymagane, aby działał. Kopiujemy poniżej i rozszerzamy zawartość tej strony * w celach informacyjnych:
Skąd wziąć gotowe pliki binarne
Możesz pobrać gotowe pliki binarne dla systemu Windows z projektu fcml
Jak budować hsdis-amd64.dlli hsdis-i386.dllna Windowsie
Ta wersja poradnika została przygotowana na Windows 8.1 64-bitowym przy użyciu 64-bitowego Cygwin i produkując hsdis-amd64.dll
Zainstaluj Cygwin . Na Select Packagesekranie dodaj następujące pakiety (rozwijając Develkategorię, a następnie klikając raz Skipetykietę obok nazwy każdego pakietu):
makemingw64-x86_64-gcc-core(potrzebne tylko do hsdis-amd64.dll)mingw64-i686-gcc-core(potrzebne tylko do hsdis-i386.dll)diffutils(w Utilskategorii)Uruchom terminal Cygwin. Można to zrobić za pomocą ikony Pulpit lub Menu Start utworzonej przez instalator i utworzy katalog domowy Cygwin ( C:\cygwin\home\<username>\lub C:\cygwin64\home\<username>\domyślnie).
binutils-2.25.tar.bz2. Powinno to spowodować utworzenie katalogu o nazwie binutils-2.25(lub jakiejkolwiek najnowszej wersji) w katalogu domowym Cygwin.src\share\tools) do katalogu domowego Cygwin.cd ~/hsdis.Aby zbudować hsdis-amd64.dll, wejdź
make OS=Linux MINGW=x86_64-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25
Aby zbudować hsdis-i386.dll, wejdź
make OS=Linux MINGW=i686-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25
W obu przypadkach zastąp 2.25pobraną wersją binutils. OS=Linuxjest konieczne, ponieważ chociaż Cygwin jest środowiskiem podobnym do Linuksa, plik makefile hsdis nie rozpoznaje go jako takiego.
./chew: No such file or directoryi gcc: command not found. Edytuj <Cygwin home directory>\hsdis\build\Linux-amd64\bfd\Makefilew edytorze tekstu, takim jak Wordpad lub Notepad ++, aby zmienić SUBDIRS = doc po(wiersz 342, jeśli używasz binutils 2.25) na SUBDIRS = po. Ponownie uruchom poprzednie polecenie.Bibliotekę DLL można teraz zainstalować, kopiując ją z hsdis\build\Linux-amd64lub hsdis\build\Linux-i586do środowiska JRE bin\serverlub bin\clientkatalogu. Możesz znaleźć wszystkie takie katalogi w swoim systemie, wyszukując java.dll.
Dodatkowa wskazówka: jeśli wolisz składnię Intel ASM od AT&T, określ -XX:PrintAssemblyOptions=intelobok innych używanych opcji PrintAssembly.
* Licencja strony to Creative Commons
/usr/lib/
Potrzebujesz wtyczki hsdis do użycia PrintAssembly. Wygodnym wyborem jest wtyczka hsdis oparta na bibliotece FCML.
Można go skompilować dla systemów typu UNIX, aw systemie Windows można użyć gotowych bibliotek dostępnych w sekcji pobierania FCML na Sourceforge:
java.dll(użyj wyszukiwania systemu Windows). W moim systemie znalazłem go w dwóch lokalizacjach:
C:\Program Files\Java\jre1.8.0_45\bin\serverC:\Program Files\Java\jdk1.8.0_45\jre\bin\servercd <source code dir>./configure && make && sudo make installcd example/hsdis && make && sudo make installsudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/lib/amd64/hsdis-amd64.sosudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/jre/lib/amd64/hsdis-amd64.so/usr/lib/jvm/java-8-oraclejava -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
-XX:+LogCompilation -XX:PrintAssemblyOptions=intel,mpad=10,cpad=10,code
-jar fcml-test.jar
Dodatkowe parametry konfiguracyjne:
kod Wydrukuj kod maszynowy przed mnemonikiem.
intel Użyj składni Intela.
gas Używa składni asemblera AT&T (kompatybilna z GNU assembler).
dec Drukuje IMM i przemieszczenie jako wartości dziesiętne.
mpad = XX Wypełnienie mnemonicznej części instrukcji.
cpad = XX Wypełnienie kodu maszynowego.
seg Pokazuje domyślne rejestry segmentów.
zera W przypadku literałów szesnastkowych wyświetla zera wiodące.
Składnia Intela jest domyślna w przypadku Windows, podczas gdy AT&T jest domyślna dla GNU / Linux.
Aby uzyskać więcej informacji, zobacz Podręcznik referencyjny biblioteki FCML
apt-get install libhsdis0-fcml( askubuntu.com/a/991166/489909 ). Samodzielne budowanie może nie być konieczne.
W przypadku HotSpot (wcześniej Sun) JVM, nawet w trybach produktu:
http://wikis.oracle.com/display/HotSpotInternals/PrintAssembly
Wymagany montaż: wymaga wtyczki.
Wierzę, że WinDbg byłby pomocny, jeśli uruchamiasz go na komputerze z systemem Windows. Właśnie wypuściłem jeden słoik.
Przejrzałem niezarządzany stos wywołań przez 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
Wyróżnione wiersze to bezpośrednio uruchamiany kod JIT w JVM.
Następnie możemy poszukać adresu metody:
java + 0x2f68 to 00402f68
W WinDBG:
Kliknij Widok -> Demontaż.
Kliknij Edytuj -> Idź do adresu.
Umieść 00402f68 tam
i otrzymaj
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
... i tak dalej
Aby uzyskać dodatkowe informacje, tutaj znajduje się przykład śledzenia wstecznego kodu w formacie JIT ze zrzutów pamięci za pomocą eksploratora procesów i WinDbg.
Wydrukuj zespół swoich punktów aktywnych za pomocą profilerów perfasm JMH ( LinuxPerfAsmProfilerlub WinPerfAsmProfiler). JMH wymaga hsdisbiblioteki, ponieważ opiera się na PrintAssembly.