JVM에서 JIT 컴파일 된 코드를 보는 방법은 무엇입니까?
JVM에서 JIT가 생성하는 네이티브 코드를 볼 수있는 방법이 있습니까?
Sun Hotspot JVM (즉, Oracle이 java.com에서 제공 한 것)을 사용하고 있다고 가정하면 플래그를 추가 할 수 있습니다.
-XX : + PrintOptoAssembly
코드를 실행할 때. 이렇게하면 JIT 컴파일러에서 생성 된 최적화 된 코드가 출력되고 나머지는 제외됩니다.
최적화되지 않은 부분을 포함하여 전체 바이트 코드를 보려면 다음을 추가하십시오.
-XX : CompileThreshold = #
코드를 실행할 때.
이 명령과 JIT의 일반적인 기능에 대한 자세한 내용은 여기 에서 읽을 수 있습니다 .
일반적인 사용법
다른 답변에서 설명했듯이 다음 JVM 옵션으로 실행할 수 있습니다.
-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
특정 방법으로 필터링
다음 구문을 사용하여 특정 메서드를 필터링 할 수도 있습니다.
-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*MyClass.myMethod
메모:
- OS 등에 따라 두 번째 인수를 따옴표 안에 넣어야 할 수도 있습니다.
- 방법이 인라인되면 일부 최적화를 놓칠 수 있습니다.
방법 : Windows에 필요한 라이브러리 설치
Windows를 실행중인 경우이 페이지 에는 빌드 및 설치 방법 hsdis-amd64.dll
과 hsdis-i386.dll
작동하는 데 필요한 지침 이 있습니다. 참조를 위해 아래를 복사하고 해당 페이지 *의 내용을 확장합니다.
미리 빌드 된 바이너리를 얻을 수있는 위치
fcml 프로젝트 에서 사전 빌드 된 Windows 용 바이너리를 다운로드 할 수 있습니다.
어떻게 구축 hsdis-amd64.dll
및 hsdis-i386.dll
Windows에서
이 버전의 가이드는 64 비트 Cygwin을 사용하고 hsdis-amd64.dll을 생성하는 Windows 8.1 64 비트에서 준비되었습니다.
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 홈 디렉토리에 이름이 지정된 디렉토리 (또는 최신 버전이 무엇이든)가 생성됩니다. - JDK 8 업데이트 저장소 로 이동하여 설치된 JRE 버전에 해당하는 태그를 선택한 다음 bz2를 클릭 하여 OpenJDK 소스를 다운로드합니다 . 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와 유사한 환경이지만 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
하여 (binutils 2.25를 사용하는 경우 342 행)SUBDIRS = po
. 이전 명령을 다시 실행하십시오.
DLL은 지금부터 복사하여 설치할 수 있습니다 hsdis\build\Linux-amd64
또는 hsdis\build\Linux-i586
귀하의 JRE의에 bin\server
또는 bin\client
디렉토리. 를 검색하여 시스템에서 이러한 모든 디렉토리를 찾을 수 있습니다 java.dll
.
보너스 팁 : AT & T보다 Intel ASM 구문을 선호하는 경우 사용 -XX:PrintAssemblyOptions=intel
하는 다른 PrintAssembly 옵션과 함께 지정 하십시오.
* 페이지 라이센스는 크리에이티브 커먼즈입니다.
를 사용하려면 hsdis 플러그인이 필요합니다 PrintAssembly
. 편리한 선택은 FCML 라이브러리를 기반으로하는 hsdis 플러그인입니다.
UNIX 계열 시스템 용으로 컴파일 할 수 있으며 Windows 에서는 Sourceforge 의 FCML 다운로드 섹션에서 사용할 수있는 미리 빌드 된 라이브러리를 사용할 수 있습니다 .
Windows에 설치하려면 :
- dll을 추출합니다 (hsdis-1.1.2-win32-i386.zip 및 hsdis-1.1.2-win32-amd64.zip에서 찾을 수 있음).
- 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 구문을 사용합니다.
gas AT & T 어셈블러 구문을 사용합니다 (GNU 어셈블러 호환 가능).
dec IMM 및 변위를 10 진수 값으로 인쇄합니다.
mpad = XX 명령어의 니모닉 부분에 대한 패딩입니다.
cpad = XX 기계어 코드의 패딩입니다.
seg 기본 세그먼트 레지스터를 표시합니다.
0 HEX 리터럴의 경우 선행 0을 표시합니다.
The Intel syntax is a default one in case of Windows, whereas the AT&T one is a default for the GNU/Linux.
For more details see the FCML Library Reference Manual
For the HotSpot (was Sun) JVM, even in product modes:
http://wikis.oracle.com/display/HotSpotInternals/PrintAssembly
Some assembly required: it needs a plugin.
I believe WinDbg would be helpful if you are running it on windows machine. I have just run one jar.
- Then I attached to the java process through Windbg
- Examined threads by ~ command; There were 11 threads, 0 thread was main worker thread
- Switched to 0-thread - ~0s
Looked through unmanmaged callstack by kb there was:
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
Highlighted lines is direct running JIT-ed code on JVM.
Then we can look for method address:
java+0x2f68 is 00402f68On WinDBG:
Click View --> Disassembly.
Click Edit --> Go to Address.
Put 00402f68 there
and got00402f68 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
... and so on
For additional info here is the Example how to trace back JIT-ed code from memory dumps using process explorer and WinDbg.
Another way to see machine code and some performance data is to use AMD's CodeAnalyst or OProfile, which have a Java plugin to visualize executing Java code as machine code.
Print the assembly of your hotspots with JMH's perfasm profilers (LinuxPerfAsmProfiler
or WinPerfAsmProfiler
). JMH does require the hsdis
library since it relies on PrintAssembly
.
참고URL : https://stackoverflow.com/questions/1503479/how-to-see-jit-compiled-code-in-jvm
'developer tip' 카테고리의 다른 글
symfony2 애플리케이션의 Angularjs (0) | 2020.10.21 |
---|---|
memcached가 어떤 일을하고 있는지 어떻게 알 수 있습니까? (0) | 2020.10.21 |
C #은 반환 형식 공분산을 지원합니까? (0) | 2020.10.21 |
System.Drawing.Color 값 설정 (0) | 2020.10.21 |
Moq, SetupGet, Mocking a property (0) | 2020.10.21 |