4. 4
실습파일 다운로드
https://www.dropbox.com/s/znp9247yjl11d7w/jadeedu_jvm_20211103.zip?dl=0
jadeedu_jvm.zip 파일을 C: 하위에 압축 해제
실습 환경설정 (1/8) - 실습파일 다운로드 및 압축 해제
실습 환경설정
jadeedu_jvm_20211103.zip
5. 5
실습 환경설정 (2/8) - VirtualBox 설치
VirtualBox 6 설치
C:jadeedu_jvmswVirtualBox-6.1.16-140961-Win.exe 더블클릭
VirtualBox 환경 설정
파일 환경설정
실습 환경설정
입력 확장
가상 머신
┗▶ 호스트 키 조합
확장 패키지 추가
Ctrl + Alt
C:jadeedu_jvmswOracle_VM_
VirtualBox_Extension_Pack-
6.1.16.vbox-extpack 선택
6. 6
실습 환경설정 (3/8) - VirtualBox 환경설정
네트워크 설정
“Tools 네트워크” 선택
IP 대역 설정
192.168.56.0/24 대역으로 네트워크 설정
실습 환경설정
192.168.56.1/24 192.168.56.1/24
192.168.56.1
192.168.56.100
192.168.56.101
192.168.56.254
7. 7
“NAT 네트워크” 추가
파일 환경 설정 네트워크“
NAT 네트워크 정보
네트워크 이름 : EduNatNetwork
네트워크 CIDR : 192.168.55.0/24
실습 환경설정 (4/8) - VirtualBox 환경설정
실습 환경설정
8. 8
실습 환경설정 (5/8) - 실습 VM 가져오기 및 실행
버튼 클릭하여 VM 가져오기
jvmedu 가상머신 실행
실습 환경설정
계정 : root
암호 : edu
“C:jadeedu_jvmvmjvmedujvmedu.vbox”
파일 선택
jvmedu.vbox
jvmedu.vbox
9. 9
실습 환경설정 (6/8) - 원격 접속
MobaXterm 실행
jvmedu VM 원격 접속
192.168.56.96
실습 환경설정
10. 10
실습 환경설정 (7/8)
실습 환경 최소 조건
Windows 10, 8G RAM, VirtualBox(하이퍼바이저) 실행 가능해야 함
SSD 디스크 사용할수록 실습이 용이함
최소 VM 자원 설정
vCPU : 4 Core
Memory : 4 GB
실습 환경설정
VirtualBox(Win 10)
jvmedu
(192.168.56.96)
internet
7080
9080
11. 11
실습 환경설정 (8/8)
JAVA_HOME 환경변수 설정
실습 환경설정
C:jadeedu_jvmswjava_tooljdk1.8.0_281
PATH 환경 변수 설정
java.exe가 실행되도록 PATH 환경변수에 %JAVA_HOME%bin 설정
13. 13
요즘 초등학교에서는?
하드웨어 및 운영체제 리뷰
https://www.youtube.com/watch?v=AkFi90lZmXA&feature=youtu.be
14. 14
컴퓨터 시스템 아키텍쳐
하드웨어 및 운영체제 리뷰
Memory
CPU
Disk
Controller
USB
Controller
Graphic
Adappter
15. 15
FETCH, DECODE, EXECUTE
하드웨어 및 운영체제 리뷰
https://www.youtube.com/watch?v=Z5JC9Ve1sfI&feature=youtu.be
https://www.youtube.com/watch?v=04UGopESS6A&feature=youtu.be
(프로그램 내장 방식)
https://youtu.be/389itBs7YlE?t=717
16. 16
메모리 계층 구조
하드웨어 및 운영체제 리뷰
https://ko.wikipedia.org/wiki/%EC%A7%90_%EA%B7%B8%EB%A0%88%EC%9D%B4
속도
가격
17. 17
프로그램 = 실행 파일 + 라이브러리
C 실행파일의 빌드 절차
하드웨어 및 운영체제 리뷰
hello.c
(소스 파일)
hello.i
(전처리된 소스파일)
hello.o
(목적 파일)
a.out
(실행 파일)
hello.s
(어셈블리 파일)
C 전처리
C 전처리기
cpp
C 컴파일
C 컴파일러
cc1
어셈블
어셈블러
as
링킹
링커
ld,collect2
사용자 작성
라이브러리
시스템 내장
라이브러리
18. 18
프로그램 -vs- 프로세스
프로그램
컴파일, 링크 과정을 거쳐 실행할 수 있는 머신코드로 디스크에 저장되어 있음
가상메모리를 사용하는 범용 OS에서는 프로그램의 코드 및 변수의 주소가 이미 결정되어짐
ELF (Executable and Linkable Format)
리눅스의 오브젝트 파일 형식 (원도우즈에서는 PE(Portable Executable) 사용)
https://ko.wikipedia.org/wiki/ELF_파일_형식
프로세스
실행중인 프로그램
하드웨어 및 운영체제 리뷰
Run-Time
19. 19
LAB) C 프로그램 빌드, 실행, 메모리 레이아웃 이해 (1/3)
Static Allocation -vs- Dynamic Allocation
하드웨어 및 운영체제 리뷰
cprog.c
#include <stdio.h>
#include <stdlib.h>
int f2(int x);
int a = 10;
int a2 = 20;
int b;
int b2;
int f1(int x) {
return ++x;
}
int main() {
int c = 100, c2;
char *d = "hello";
char *name;
int *score;
name = malloc(50);
score = malloc(20 * sizeof(int));
printf("%sn", d);
printf("addr(TEXT) => main:%p, f1:%p, f2:%pn", main, f1, f2);
printf("addr(CONST) => d:%pn", d);
printf("addr(DATA) => a:%p, a2:%pn", &a, &a2);
printf("addr(BSS) => b:%p, b2:%pn", &b, &b2);
printf("addr(STACK) => c:%p, c2:%pn", &c, &c2);
printf("addr(HEAP) => name:%p, score:%pn", name, score);
return 0;
}
int f2(int x) {
return --x;
}
프로그램
(HDD)
코드/상수
Static
Allocation
TEXT
초기화된 전역변수와 정적변수 DATA
초기화되지 않은 전역변수와 정적변수 BSS
프로세스
(RAM)
코드/상수
Static
Allocation
TEXT
초기화된 전역변수와 정적변수 DATA
초기화되지 않은 전역변수와 정적변수
(0으로 자동 초기화) BSS
동적 할당 메모리
(포인터로 접근)
Dynamic
Allocation
HEAP
지역변수
함수 인자와 리턴 값 STACK
실행
20. 20
LAB) C 프로그램 빌드, 실행, 메모리 레이아웃 이해 (2/3)
C 프로그램 빌드 및 주소 확인
하드웨어 및 운영체제 리뷰
C 언어 소스를 빌드하여 실행파일 생성
[root@jvmedu ~]# cd ~/lab/cprogram
[root@jvmedu cprogram]# gcc cprog.c
[root@jvmedu cprogram]# ls -l
total 16
-rwxr-xr-x 1 root root 8624 Oct 18 14:12 a.out
-rw-r--r-- 1 root root 689 Oct 18 14:10 cprog.c
빌드된 실행파일의 형식을 확인
[root@jvmedu cprogram]# file a.out
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs),
for GNU/Linux 2.6.32, BuildID[sha1]=d97dd1cd5b319eb15e2d7fe252100ad309f8c1b7, not stripped
a.out 실행파일의 변수 및 함수의 주소를 확인
[root@jvmedu cprogram]# readelf -a a.out 또는 nm a.out 으로 주소 확인
Section Headers:
[Nr] Name Type Address Offset Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040 0000000000000027 0000000000000000 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 00000200 0000000000000030 0000000000000018 I 10 1 8
[ 3] .data PROGBITS 0000000000000000 00000067 0000000000000000 0000000000000000 WA 0 0 1
[ 4] .bss NOBITS 0000000000000000 00000067 0000000000000000 0000000000000000 WA 0 0 1
[ 5] .rodata PROGBITS 0000000000000000 00000067 000000000000000a 0000000000000000 A 0 0 1
[ 6] .comment PROGBITS 0000000000000000 00000071 000000000000002e 0000000000000001 MS 0 0 1
[ 7] .note.GNU-stack PROGBITS 0000000000000000 0000009f 0000000000000000 0000000000000000 0 0 1
[ 8] .eh_frame PROGBITS 0000000000000000 000000a0 0000000000000038 0000000000000000 A 0 0 8
[ 9] .rela.eh_frame RELA 0000000000000000 00000230 0000000000000018 0000000000000018 I 10 8 8
[10] .symtab SYMTAB 0000000000000000 000000d8 0000000000000108 0000000000000018 11 9 8
[11] .strtab STRTAB 0000000000000000 000001e0 000000000000001c 0000000000000000 0 0 1
[12] .shstrtab STRTAB 0000000000000000 00000248 0000000000000061 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude), l (large), p (processor specific)
...
21. 21
LAB) C 프로그램 빌드, 실행, 메모리 레이아웃 이해 (3/3)
프로그램을 실행하여 프로세스 상태의 메모리 레이아웃 이해
하드웨어 및 운영체제 리뷰
a.out 프로그램을 실행하고 결과를 보고 프로세스의 메모리 레이아웃에 대해 이해
[root@jvmedu cprogram]# ./a.out
hello
addr(TEXT) => main:0x4005cd, f1:0x4005bd, f2:0x4006ad
addr(CONST) => d:0x400750
addr(DATA) => a:0x601044, a2:0x601048
addr(BSS) => b:0x601050, b2:0x601054
addr(STACK) => c:0x7fff55dabff4, c2:0x7fff55dabff0
addr(HEAP) => name:0xbbf010, score:0xbbf050
22. 22
정적 링킹 (Static Linking) 동적 링킹 (Dynamic Linking)
최종 실행파일에 필요한 오브젝트 파일들을 미리 링크하여 실행파일에
포함
실행파일만 있으면 별도의 파일 없이 실행 가능함
실행파일의 크기가 커지고 라이브러리 갱신 시 모든 파일의 재 컴파일
필요
정적 링킹은 라이브러리 코드가 실행 파일 내에 저장되기 때문에 배포
와 설치를 간단하게 만듦
최종 실행파일에 필요한 오브젝트 파일들을 미리 링크하지 않고, 실행
하려고 할 때 필요한 프로그램 모듈을 결합하여 실행을 계속함
실행파일의 크기가 작음
실행파일 이외의 별도의 필요한 모듈을 제공해야 함
종류
Build-time Linking
Run-time Linking
링킹(Linking)의 종류
하드웨어 및 운영체제 리뷰
23. 23
LAB) 링킹 방법 및 링킹 정보 확인 (1/2)
링킹 방법
Dynamic Linking
디폴트 - 아무런 옵션 없이 사용
Static Linking
링크 작업시 -static 옵션 사용
하드웨어 및 운영체제 리뷰
cprog.c
#include <stdio.h>
#include <stdlib.h>
int f2(int x);
int a = 10;
int b;
int a2 = 20;
int b2;
int f1(int x) {
return ++x;
}
int main() {
int c = 100, c2;
char *d = "hello";
char *name;
int *score;
name = malloc(50);
score = malloc(20 * sizeof(int));
printf("%sn", d);
printf("addr(TEXT) => main:%p, f1:%p, f2:%pn", main, f1, f2);
printf("addr(CONST) => d:%pn", d);
printf("addr(DATA) => a:%p, a2:%pn", &a, &a2);
printf("addr(BSS) => b:%p, b2:%pn", &b, &b2);
printf("addr(STACK) => c:%p, c2:%pn", &c, &c2);
printf("addr(HEAP) => name:%p, score:%pn", name, score);
return 0;
}
int f2(int x) {
return --x;
}
24. 24
LAB) 링킹 방법 및 링킹 정보 확인 (2/2)
하드웨어 및 운영체제 리뷰
Dynamic Linking Static Linking
cprog.c 소스파일을 Dynamic Linking으로 a.out_dynamic 실행 파일을 빌드 cprog.c 소스파일을 Static Linking으로 a.out_static 실행 파일 빌드
[root@jvmedu ~]# cd ~/lab/cprogram
[root@jvmedu cprogram]# gcc cprog.c -o a.out_dynamic
[root@jvmedu ~]# cd ~/lab/cprogram
[root@jvmedu cprogram]# gcc -static cprog.c -o a.out_static
빌드된 a.out_dynamic 실행파일의 파일 정보 확인 빌드된 a.out_static 실행파일의 파일 정보 확인
[root@jvmedu cprogram]# file a.out_dynamic
a.out_dynamic: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.32,
BuildID[sha1]=fef585c519097eb7b47761185909d8d20ec47545, not stripped
[root@jvmedu cprogram]# file a.out_static
a.out_static: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux),
statically linked, for GNU/Linux 2.6.32,
BuildID[sha1]=c6acb31c946e031cd81c5c9e54fb55ab2ff73675, not stripped
빌드된 a.out_dynamic 실행파일의 SYMBOL 정보 확인 빌드된 a.out_static 실행파일의 SYMBOL 정보 확인
[root@jvmedu 01]# nm a.out_dynamic
000000000060103c D a
0000000000601040 D a2
0000000000601048 B b
000000000060104c B b2
0000000000601044 B __bss_start
0000000000601044 b completed.6355
0000000000601038 D __data_start
0000000000601038 W data_start
00000000004004f0 t deregister_tm_clones
0000000000400560 t __do_global_dtors_aux
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
0000000000400738 R __dso_handle
0000000000600e28 d _DYNAMIC
...
[root@jvmedu 01]# nm a.out_static
00000000006bd084 D a
00000000006bd088 D a2
000000000041ce80 T abort
00000000006bf730 B __abort_msg
000000000043de60 W access
000000000043de60 T __access
0000000000490dd0 t add_fdes
000000000044b700 t add_module.isra.1
0000000000440d90 t add_name_to_object.isra.2
00000000006be708 d adds.8362
000000000041d300 T __add_to_environ
0000000000488690 t add_to_global
00000000006bf4c0 V __after_morecore_hook
...
Dynamic Linking된 바이너리와 Static Linking된 바이너리의 사이즈 비교
[root@jvmedu cprogram]# ls -lh a.out_*
-rwxr-xr-x 1 root root 8.6K Oct 24 14:51 a.out_dynamic
-rwxr-xr-x 1 root root 842K Oct 24 20:05 a.out_static
Static Linking의
사이즈가 97배 더 큼
25. 25
LAB) Shared Library 제작 (1/2)
Shared Library 제작
gcc -c -fPIC max.c
gcc -c -fPIC min.c
gcc -shared -o libtest.so max.o min.o
하드웨어 및 운영체제 리뷰
max.c 와 min.c를 빌드하여 object 파일이 생성되었는지 확인
[root@jvmedu ~]# cd ~/lab/cprogram/libTest1/libSrc
[root@jvmedu libSrc]# gcc -c max.c min.c
[root@jvmedu libSrc]# ls -l *.o
-rw-r--r-- 1 root root 1248 Oct 24 15:37 max.o
-rw-r--r-- 1 root root 1248 Oct 24 15:37 min.o
gcc의 -shared 옵션으로 libtest.o 라는 Shared Library 생성하고 파일 정보를 확인
[root@jvmedu libSrc]# gcc -shared -o libtest.so max.o min.o
[root@jvmedu libSrc]# file libtest.so
libtest.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically
linked, BuildID[sha1]=f2167ffbae307a30ecde862fd12777949ce917d4, not stripped
[라이브러리 실습 소스]
26. 26
LAB) Shared Library 제작 (2/2)
Shared Library 이용
gcc -c -I<라이브러리헤더파일위치> app.c
gcc app.o -ltest -L<정적라이브러리위치>
하드웨어 및 운영체제 리뷰
[라이브러리 실습 소스]
appSrc 폴더로 이동하여, app.c 소스파일을 빌드하여 object 파일을 생성
[root@jvmedu ~]# cd ~/lab/cprogram/libTest1/appSrc
[root@jvmedu appSrc]# gcc -c -I ../include/ app.c
-L 옵션으로 Library 위치를 명시하고 링크를 수행하고, 실행파일의 파일 정보를 확인
[root@jvmedu appSrc]# gcc app.o -ltest -L ../libSrc/
[root@jvmedu appSrc]# file a.out
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked
(uses shared libs), for GNU/Linux 2.6.32,
BuildID[sha1]=91e33185650af97a7869a15687fdcaa324efd8bb, not stripped
링크된 실행파일을 실행해보고 정상 수행되는지 확인하고, 실패하는 원인은?
[root@jvmedu appSrc]# ./a.out
./a.out: error while loading shared libraries: libtest.so: cannot open shared
object file: No such file or directory
LD_LIBRARY_PATH 환경변수에 libtest.so 파일경로를 추가하고, a.out 실행
[root@jvmedu appSrc]# export
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/lab/cprogram/libTest1/libSrc
[root@jvmedu appSrc]# ./a.out
max(5, 2) : 5
min(5, 2) : 2
a.out 실행파일에 포함된 동적 라이브러를 확인
[root@jvmedu appSrc]# ldd a.out
linux-vdso.so.1 => (0x00007ffd495e4000)
libtest.so => /root/lab/cprogram/libTest1/libSrc/libtest.so (0x00007fa4615ba000)
libc.so.6 => /lib64/libc.so.6 (0x00007fa4611ec000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa4617bc000)
27. 27
LAB) Runtime Loading + Linking 되는 동적 라이브러리 (1/2)
동적 라이브러리 인터페이스 함수
하드웨어 및 운영체제 리뷰
#include <dlfcn.h>
/* Open the shared object FILE and map it in; return a handle that can be
passed to `dlsym' to get symbol values from it. */
void *dlopen(const char *filename, int flag);
/* Find the run-time address in the shared object HANDLE refers to
of the symbol called NAME. */
void *dlsym(void *handle, const char *symbol);
/* Unmap and close a shared object opened by `dlopen'.
The handle cannot be used again after calling `dlclose'. */
int dlclose(void *handle);
/* When any of the above functions fails, call this function
to return a string describing the error. Each call resets
the error string so that a following call returns null. */
char *dlerror(void);
flag 의미
RTLD_LAZY
동적 라이브러리가 실행되면서 코드의 정의되지 않은 심볼을 처리
정의되지 않은 심볼이 있으면 알아볼 수 없는 에러 발생
RTLD_NOW
dlopen()이 리턴하기 전에 모든 정의되지 않은 심볼을 처리하고,
그것이 되지 않을 경우 실패. 디버깅시 사용
RTLD_GLOBAL
라이브러리에 적제되는 외부 심볼들은 그 후에 적재되는 라이브러리에
의해서 가능함
라이브러리를 여는데 약간의 시간이 더 걸림
28. 28
LAB) Runtime Loading + Linking 되는 동적 라이브러리 (2/2)
동적 라이브러리 사용 절차
1) 공유 라이브러리 제작 & LD_LIBRARY_PATH에 등록
2) 동적 라이브러리를 사용하는 응용프로그램 작성 : dltest.c
3) 동적 라이브러리를 이용하는 응용프로그램 컴파일
4) 동적 라이브러리를 사용한 응용프로그램 실행
동적 라이브러리 실습
하드웨어 및 운영체제 리뷰
dltest.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
typedef int (*FP)(int, int);
int main(void) {
void *handle;
FP fp_max, fp_min;
char *error;
handle = dlopen("libtest.so", RTLD_LAZY);
if (!handle) {
fputs(dlerror(), stderr);
exit(1);
}
fp_max = dlsym(handle, "max");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s", error);
exit(1);
}
fp_min = dlsym(handle, "min");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s", error);
exit(1);
}
printf("max(7, 4) : %dn", fp_max(7, 4));
printf("min(5, 2) : %dn", fp_min(5, 2));
dlclose(handle);
return 0;
}
① 공유 라이브러리 제작 & LD_LIBRARY_PATH에 등록
앞 슬라이드에서 작업 완료
② 동적 라이브러리를 사용하는 응용프로그램 작성 : dltest.c
옆의 소스 참고
③ 동적 라이브러리를 이용하는 응용프로그램 컴파일
[root@jvmedu ~]# cd ~/lab/cprogram
[root@jvmedu cprogram]# gcc dltest.c -ldl
④ 동적 라이브러리를 사용한 응용프로그램 실행
[root@jvmedu cprogram]# ./a.out
max(7, 4) : 7
min(5, 2) : 2
a.out 실행파일에 libtest.so 동적 라이브러리 정보가 링크되지 않았음을 확인
[root@jvmedu cprogram]# ldd a.out
linux-vdso.so.1 => (0x00007ffe25de1000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fc92e4f2000)
libc.so.6 => /lib64/libc.so.6 (0x00007fc92e124000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc92e6f6000)
Runtime Loading
Runtime
Linking
31. 31
WOCA WORA
Write Once Run Anywhere
Java Virtual Machine
JAVA의 철학(WORA)을 실현하기 위한 4가지 기술
① Java Programming Language
② Java Class File Format
③ Java Application Programming Interface
④ Java Virtual Machine
32. 32
JAVA 프로그램 수행 과정
Java Virtual Machine
A.java
A.java B.java
B.java C.java
C.java
Java
compiler
A.class
A.class B.class
B.class C.class
C.class
Java source file
Java class file
Object.class
Object.class String.class
String.class
Java API’s class files
Java class file
A.class
A.class B.class
B.class C.class
C.class
Java Virtual
Machine
Compile
Time
Compile
Time
Run
Time
Run
Time
① Java Programming Language
② Class File Format
③ API
④ JVM
33. 33
① Java Programming Language
Java Virtual Machine
object-orientation
multi-threading
structured error-handling
garbage collection
dynamic linking
dynamic extension
Source Code의 재사용
Memory관리에서 해방
Array bound check를 통한 Program의
corruption방지
Object Reference check를 통한 Null
Reference 방지
최신 Software 기술의 적용
최신 Software 기술의 적용
생산성의 극대화
생산성의 극대화
Java Virtual Machine
Other Class
Runtime Memory를
직접 핸들링하지 않음
Dynamic Linking
Linking : 개발한 코드에 표준 라이브러리를 연결하는 작업
Class 파일은 JVM에 로드 된 후 실행이 가능한 형태로 변환되는데, 이
때 표준 라이브러리와 Linking이 수행됨
Class 파일 사이즈가 적음
이러한 Link작업이 필요할 때마다 동적으로 이루어짐
34. 34
② Java Class File Format
Class File Format
Network Byte Order 사용
서로 다른 계열의 CPU끼리 데이터 통신시 Byte Order(Big Endian/Little Endian)에 상관없이 전송하기 위한 규약
Compact한 형태
ByteCode로 변경
Platform 독립적
Java Virtual Machine
Presentation
Presentation
클래스파일
Introduction to Class File Format Byte Code.pptx
https://www.dropbox.com/s/djz1ogobx38s9v7/Introduction%20to%20Class%20File%20Format%20%26%20Byte%20Code.pptx?dl=0
Class File Format Image
https://www.dropbox.com/s/dcesinbnh0g7dmj/%ED%81%B4%EB%9E%98%EC%8A%A4%ED%8C%8C%EC%9D%BC%ED%8F%AC%EB%A7%B7.png?dl=0
35. 35
③ Java API(Application Programming Interface) (1/2)
Runtime Library의 집합
Platform Independent
java -XshowSettings:properties -version
sun.boot.class.path
Java Virtual Machine
Java API
Java Class
Linux
Linux
jvm.so
jvm.so
Java API
Java Class
jvm.dll
jvm.dll
Windows
Windows
Java API
Java Class
Others
Others
jvm.xxx
Native Library (Dynamic Linking)
Host Operating System
38. 38
④ Java Virtual Machine (2/3)
자바를 위한 가상의 머신
Java Virtual Machine
Java API
Java Class
Linux
Linux
jvm.so
Java API
Java Class
jvm.dll
Windows
Windows
Java API
Java Class
Others
Others
jvm.xxx
Java
Virtual
Machine
Host Operating System
39. 39
④ Java Virtual Machine (3/3)
JVM Architecture
① Class Loader System을 통해 Class 파일들을 JVM으로 로딩한다.
② 로딩된 Class 파일들은 Execution Engine에 의해 해석된다.
③ 이렇게 해석된 프로그램은 Runtime Data Area 배치되어 실질적인 수행이 이루어지게 된다.
④ 이러한 실행 과정 속에서 JVM은 필요에 따라 Thread Synchronization과 Garbage Collection 같은 관리작업을 수행하게 된다
Java Virtual Machine
Java Application
(Real-Time) Operating System
Native
Method
Libraries
Class
Libraries
Class Loader System
Execution
Engine
Run-time
Data Area
Garbage
Collector
Java
Threads
Native
Threads
40. 40
JVM 히스토리
Java Virtual Machine
https://www.geeksforgeeks.org/the-complete-history-of-java-programming-language/
-javaagent
옵션 추가
Modern JAVA
Microsoft Word
문서
42. 42
참고) JVM 구현체 (2/3)
Java Virtual Machine
Vendor Product Commercial Architecture Description
ORACLE Oracle JDK Commercial Hotspot
Java 8 2019년 1월 이후 License 필요
검토 시 기준 값으로 사용
AZUL Zing Commercial Zing
Azul의 자체 아키텍처를 가진 JVM
상용버전으로, 아키텍처가 독특함
OpenJDK.org OpenJDK OSS Hotspot
썬 마이크로시스템즈 시절에 만들어진 커뮤니티 그룹으로 OpenJDK가 만들어지는 곳
커뮤니티에 집중되어 있고 Source는 배포하지만
Binary 배포는 https://jdk.java.net을 통하여 이루어짐
https://jdk.java.net에서 배포되는 Binary는 참조용으로 사용할 것을 권장
AZUL Zulu OSS Hotspot
Azul에서 오픈소스로 제공하는 JDK
Zing과는 아키텍처 자체가 다르며, OpenJDK를 기반으로 개발되지만 별도의 계약으로 지원을 받을
수 있음
Red Hat/CentOS OpenJDK OSS Hotspot
레드햇에서 RHEL(Red Hat Enterprise Linux) 또는 CentOS yum repository를 통하여 rpm(binary)으
로 배포
OS 버전에 따라서 지원되는 버전이 조금씩 다름
AdoptOpenJDK.net OpenJDK OSS
Hotspot
OpenJ9
OpenJDK 배포를 주 목적으로 하며, 여러 기업의 후원을 받아 개발자들이 운영하는 커뮤니티
오라클의 지원으로 OpenJDK.org가 주도하는 Hotspot(openjdk)과, IBM의 지원으로 Eclipse가 주도
하는 OpenJ9 VM의 Binary를 모두 제공
다양한 플랫폼과 VM아키텍처의 Binary를 제공 받을 수 있음
Eclipse.org OpenJ9 OSS OpenJ9
(IBM)
IBM이 자체 JDK를 Eclipse에 기부하면서 시작된 프로젝트로 VM 아키텍처가 Hotspot과 다름
IBM 계열의 JDK를 사용 중이던 기업에서 OpenJDK를 고려할 경우 OpenJ9을 고려할 수 있음
기존의 Hotspot 계열의 JVM과 설정 및 아키텍처에서 다수의 차이가 있음
43. 43
참고) JVM 구현체 (3/3)
VM Options Explorer
https://chriswhocodes.com
Java Virtual Machine
44. 44
JVM Option
JAVA Option
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html#CBBIJCHG
Java Virtual Machine
Standard Option Non-standard Option
모든 JVM에 공통인 Option
JVM버전에 따라 다름
설정 값, 성능개선 등의 Parameter 등이 포함
- 뒤에 옵션이 들어감 -X option -XX option
Macro한 측면의 제어 Micro한 측면의 제어
Boolean
on : -XX:+option
off : -XX:-option
설정된 Option을 끄거나 새로운 기능을 추가하기 위해 사용
Numeric -XX:option=number
보통 용량 설정
• k, K - Kilobyte
• m, M - Megabyte
• g, G - Gigabyte
• 단위가 없으면 byte로 인식
String -XX:option=string 특정 파일 또는 Path 의 지정에 많이 사용
Non-standard Option
Standard Option
JVM Option -X Option
-XX Option
45. 45
LAB) JVM Standard 옵션 확인
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
Java Virtual Machine
[root@jvmedu ~]# java -help
Usage: java [-options] class [args...]
(to execute a class)
or java [-options] -jar jarfile [args...]
(to execute a jar file)
where options include:
-d32 use a 32-bit data model if available
-d64 use a 64-bit data model if available
-server to select the server VM
The default VM is server,
because you are running on a server-class machine.
-cp class search path of directories and zip/jar files
-classpath class search path of directories and zip/jar files
A : separated list of directories, JAR archives,
and ZIP archives to search for class files.
-Dname=value
set a system property
-verbose:[class|gc|jni]
enable verbose output
-version print product version and exit
-version:value
Warning: this feature is deprecated and will be removed
in a future release.
require the specified version to run
-showversion print product version and continue
-jre-restrict-search | -no-jre-restrict-search
Warning: this feature is deprecated and will be removed
in a future release.
include/exclude user private JREs in the version search
-? -help print this help message
-X print help on non-standard options
-ea[:packagename...|:classname]
-enableassertions[:packagename...|:classname]
enable assertions with specified granularity
-da[:packagename...|:classname]
-disableassertions[:packagename...|:classname]
disable assertions with specified granularity
-esa | -enablesystemassertions
enable system assertions
-dsa | -disablesystemassertions
disable system assertions
-agentlib:libname[=options]
load native agent library libname, e.g. -agentlib:hprof
see also, -agentlib:jdwp=help and -agentlib:hprof=help
-agentpath:pathname[=options]
load native agent library by full pathname
-javaagent:jarpath[=options]
load Java programming language agent
, see java.lang.instrument
-splash:imagepath
show splash screen with specified image
See http://www.oracle.com/technetwork/java/javase/documentation/index.html
for more details.
46. 46
LAB) JVM Non-Standard -X 옵션 확인
Java Virtual Machine
[root@jvmedu ~]# java -X
-Xmixed mixed mode execution (default)
-Xint interpreted mode execution only
-Xbootclasspath:directories and zip/jar files separated by :
set search path for bootstrap classes and resources
-Xbootclasspath/a:directories and zip/jar files separated by :
append to end of bootstrap class path
-Xbootclasspath/p:directories and zip/jar files separated by :
prepend in front of bootstrap class path
-Xdiag show additional diagnostic messages
-Xnoclassgc disable class garbage collection
-Xincgc enable incremental garbage collection
-Xloggc:file log GC status to a file with time stamps
-Xbatch disable background compilation
-Xmssize set initial Java heap size
-Xmxsize set maximum Java heap size
-Xsssize set java thread stack size
-Xprof output cpu profiling data
-Xfuture enable strictest checks, anticipating future default
-Xrs reduce use of OS signals by Java/VM (see documentation)
-Xcheck:jni perform additional checks for JNI functions
-Xshare:off do not attempt to use shared class data
-Xshare:auto use shared class data if possible (default)
-Xshare:on require using shared class data, otherwise fail.
-XshowSettings show all settings and continue
-XshowSettings:all show all settings and continue
-XshowSettings:vm show all vm related settings and continue
-XshowSettings:system (Linux Only) show host system or container configuration and continue
-XshowSettings:properties show all property settings and continue
-XshowSettings:locale show all locale related settings and continue
The -X options are non-standard and subject to change without notice.
47. 47
LAB) JVM 디폴트 설정 값 확인 (1/2)
Java Virtual Machine
vm 디폴트 설정 값 확인
[root@jvmedu ~]# java -XshowSettings:vm -version
VM settings:
Max. Heap Size (Estimated): 878.50M
Ergonomics Machine Class: server
Using VM: OpenJDK 64-Bit Server VM
Locale 디폴트 설정 값 확인
[root@jvmedu ~]# java -XshowSettings:locale -version
Locale settings:
default locale = English
default display locale = English (United States)
default format locale = English (United States)
available locales = , ar, ar_AE, ar_BH, ar_DZ, ar_EG, ar_IQ, ar_JO,
ar_KW, ar_LB, ar_LY, ar_MA, ar_OM, ar_QA, ar_SA, ar_SD,
ar_SY, ar_TN, ar_YE, be, be_BY, bg, bg_BG, ca,
ca_ES, cs, cs_CZ, da, da_DK, de, de_AT, de_CH,
de_DE, de_GR, de_LU, el, el_CY, el_GR, en, en_AU,
en_CA, en_GB, en_IE, en_IN, en_MT, en_NZ, en_PH, en_SG,
en_US, en_ZA, es, es_AR, es_BO, es_CL, es_CO, es_CR,
es_CU, es_DO, es_EC, es_ES, es_GT, es_HN, es_MX, es_NI,
es_PA, es_PE, es_PR, es_PY, es_SV, es_US, es_UY, es_VE,
et, et_EE, fi, fi_FI, fr, fr_BE, fr_CA, fr_CH,
fr_FR, fr_LU, ga, ga_IE, hi, hi_IN, hr, hr_HR,
hu, hu_HU, in, in_ID, is, is_IS, it, it_CH,
it_IT, iw, iw_IL, ja, ja_JP, ja_JP_JP_#u-ca-japanese, ko, ko_KR,
lt, lt_LT, lv, lv_LV, mk, mk_MK, ms, ms_MY,
mt, mt_MT, nl, nl_BE, nl_NL, no, no_NO, no_NO_NY,
pl, pl_PL, pt, pt_BR, pt_PT, ro, ro_RO, ru,
ru_RU, sk, sk_SK, sl, sl_SI, sq, sq_AL, sr,
sr_BA, sr_BA_#Latn, sr_CS, sr_ME, sr_ME_#Latn, sr_RS, sr_RS_#Latn, sr__#Latn,
sv, sv_SE, th, th_TH, th_TH_TH_#u-nu-thai, tr, tr_TR, uk,
uk_UA, vi, vi_VN, zh, zh_CN, zh_HK, zh_SG, zh_TW
Automatic Selection
Java 5 부터 자동으로 Garbage Collector, Heap Size등을 자동으
로 선택
Hardware Resource와 OS정보가 기준
Sever Class와 Client Class의 구분
java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=64717248
-XX:MaxHeapSize=1035475968
-XX:+PrintCommandLineFlags
-XX:+UseCompressedClassPointers
-XX:+UseCompressedOops
-XX:+UseParallelGC
openjdk version 1.8.0_302
OpenJDK Runtime Environment (Temurin)(build 1.8.0_302-b08)
OpenJDK 64-Bit Server VM (Temurin)(build 25.302-b08, mixed
mode)
51. 51
Runtime Data Area의 구조
Runtime Data Area
Class files
Run-Time Data Area
Method Area
Method Area Heap
Heap JVM Stacks
JVM Stacks
PC Register
PC Register
native method interface
native
method
libraries
Class libraries
“Process로서의 JVM이 프로그램을 수행하기 위해 OS로 부터 할당 받은 메모리 영역“
Native
Method Stacks
Native
Method Stacks
모든 Thread에 공유됨 Thread별로 생성
Class Loader
subsystem
Class Loader
subsystem
Execution
engine
Execution
engine
52. 52
PC(Program Counter) Register (1/2)
JVM 스펙 문서의 PC Register
The Java Virtual Machine can support many threads of execution at once. Each Java Virtual Machine
thread has its own pc (program counter) register. At any point, each Java Virtual Machine thread is
executing the code of a single method, namely the current method for that thread. If that method is
not native, the pc register contains the address of the Java Virtual Machine instruction currently
being executed. If the method currently being executed by the thread is native, the value of the Java
Virtual Machine's pc register is undefined. The Java Virtual Machine's pc register is wide enough to
hold a returnAddress or a native pointer on the specific platform.
(참고) 프로세서(CPU)의 프로그램 실행 절차
Runtime Data Area
FETCH
DECODE
EXECUTE
53. 53
PC(Program Counter) Register (2/2)
현재 작업하는 내용(Byte Code Instruction)을 CPU에 instruction으로 제공할 때 사용하는 버퍼 공간
Thread 별로 하나씩 존재하며, Thread가 시작될 때 생성됨
Thread가 java method를 수행하고 있다면, PC Register에는 현재 수행중인 JVM Instruction을 주소를 가지고 있게 된다.
Runtime Data Area
Thread PC register (Program Counter)
Create
Start
Java Method Call { … }
Native Pointer
Native Pointer
or
Return Address
Current Instruction Address
Current Instruction Address
(native pointer or
method bytecode 시작 offset)
undefined
Native Method Call
54. 54
Java Virtual Machine Stacks (1/2)
JVM 스펙의 JVM Stacks
Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread. A Java Virtual
Machine stack stores frames. A Java Virtual Machine stack is analogous to the stack of a conventional language such as C: it holds local
variables and partial results, and plays a part in method invocation and return. Because the Java Virtual Machine stack is never
manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java Virtual Machine stack does
not need to be contiguous.
In the First Edition of The Java® Virtual Machine Specification, the Java Virtual Machine stack was known as the Java stack.
This specification permits Java Virtual Machine stacks either to be of a fixed size or to dynamically expand and contract as required by
the computation. If the Java Virtual Machine stacks are of a fixed size, the size of each Java Virtual Machine stack may be chosen
independently when that stack is created.
A Java Virtual Machine implementation may provide the programmer or the user control over the initial size of Java Virtual Machine stacks, as well as, in
the case of dynamically expanding or contracting Java Virtual Machine stacks, control over the maximum and minimum sizes.
Runtime Data Area
④
③
②
①
삽입(push) 제거(pop)
①②③④의 순서로 데이터 삽입 ④③②①의 순서로 데이터 제거
스택의 상위(Top)
[그림 5-2] 스택의 구조
The following exceptional conditions are associated with Java Virtual
Machine stacks:
If the computation in a thread requires a larger Java Virtual Machine stack than
is permitted, the Java Virtual Machine throws a StackOverflowError.
If Java Virtual Machine stacks can be dynamically expanded, and expansion is
attempted but insufficient memory can be made available to effect the
expansion, or if insufficient memory can be made available to create the initial
Java Virtual Machine stack for a new thread, the Java Virtual Machine throws an
OutOfMemoryError.
55. 55
Java Virtual Machine Stacks (2/2)
Runtime Data Area
Java
Stack
Java
Stack
Thread
Java
Stack
Java
Stack
Thread
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Thread
Thread
Java
Stack
Java Stacks
Java Stack은 Thread의 상태 값을 저장
Thread당 1개의 Stack Area
Stack의 모든 데이터는 Thread의 소유
다른 Thread 접근 불허
Implement는 JVM Vendor의 재량
Stack Frame들로 구성됨
Thread 가 Java Method 를 하나 수행하게 되면 JVM 은 Stack Frame 을 하
나 생성 하여 JVM Stacks 에 Push
Stack Trace
‘kill -3 pid’로 생성되는 Thread Dump는 Stack Frame을 한라인으로 표시한 것
56. 56
LAB) Stack Trace (Thread Dump) 확인 (1/3)
jpetstore 샘플 웹어플리케이션 실행
Runtime Data Area
STS를 실행하고 “Tomcat v8.5” 서버 시작
[root@jvmedu ~]# sts
http://192.168.56.96:8080/jpetstore URL로 접속
Tomcat 시작
http://192.168.56.96:8080/jpetstore/
57. 57
LAB) Stack Trace (Thread Dump) 확인 (2/3)
VisualVM
https://visualvm.github.io/
Runtime Data Area
visualvm 프로그램을 설치하고 Alias 를 등록하고 visualvm 실행 후 visualgc 플러그인 설치
Tools Plugins Available Plugins Visual GC Install
[root@jvmedu ~]# cd ~/lab/java-tool
[root@jvmedu java-tool]# unzip visualvm_211.zip
[root@jvmedu java-tool]# echo alias visualvm='/root/lab/java-tool/visualvm_211/bin/visualvm /dev/null 21 ' ~/.bashrc
[root@jvmedu java-tool]# source ~/.bash_profile
[root@jvmedu java-tool]# visualvm
Applications 뷰에서 “Tomcat” 오픈 “Threads” 탭 “Thread Dump” 버튼 클릭
58. 58
LAB) Stack Trace (Thread Dump) 확인 (3/3)
Stack Trace 내용 확인
Runtime Data Area
60. 60
Stack Frame (1/7)
JVM 스펙 상의 Stack Frame
A frame is used to store data and partial results, as well as to perform dynamic linking, return values for methods, and dispatch
exceptions.
A new frame is created each time a method is invoked. A frame is destroyed when its method invocation completes, whether that
completion is normal or abrupt (it throws an uncaught exception). Frames are allocated from the Java Virtual Machine stack (§2.5.2) of
the thread creating the frame. Each frame has its own array of local variables (§2.6.1), its own operand stack (§2.6.2), and a reference to
the runtime constant pool (§2.5.5) of the class of the current method.
A frame may be extended with additional implementation-specific information, such as debugging information.
Runtime Data Area
61. 61
Stack Frame (2/7)
Stack Frame
Thread가 수행하고 있는 Application을 Method단위로 기록하는 곳.
3부분으로 구성됨(Local Variable Section, Operand Stack, Frame Data)
Method를 호출할 때 Class의 메타정보를 이용하여 적절한 크기(Compile-Time에 이미 결정됨)로 Stack Frame을 생성하여 JVM Stack에 Push 한 후
Method를 실행한다.
StackTrace는 각 Stack Frame 을 한 라인으로 표현한 것이다.
Runtime Data Area
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Thread
Thread
JvM
Stack
Local Variable
Section
Operand Stack
Frame Data
Method Parameters
Local Variables
JVM의 Work Space
Constant pool Resolution
Normal Method Return
Exception Dispatch
62. 62
Stack Frame (3/7)
Local Variable Section (1/3)
Method의 지역변수(Parameter variable, Local variable)를 저장하는 곳
0-Base 배열로 구성되어 있고, 배열의 index를 통해 data access
Method parameter는 선언된 순서대로 index가 할당되며, Local variable은 compiler가 알아서 index 할당
Runtime Data Area
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Thread
Thread
JvM
Stack
Local Variable
Section
Operand Stack
Frame Data
Method Parameters
Local Variables
JVM의 Work Space
Constant pool Resolution
Normal Method Return
Exception Dispatch
63. 63
Stack Frame (4/7)
Local Variable Section (2/3) - JVM 8 스펙문서
Each frame (§2.6) contains an array of variables known as its local variables. The length of the local variable array of a frame is
determined at compile-time and supplied in the binary representation of a class or interface along with the code for the method
associated with the frame (§4.7.3).
A single local variable can hold a value of type boolean, byte, char, short, int, float, reference, or returnAddress. A pair of local variables
can hold a value of type long or double.
Local variables are addressed by indexing. The index of the first local variable is zero. An integer is considered to be an index into the
local variable array if and only if that integer is between zero and one less than the size of the local variable array.
A value of type long or type double occupies two consecutive local variables. Such a value may only be addressed using the lesser
index. For example, a value of type double stored in the local variable array at index n actually occupies the local variables with indices
n and n+1; however, the local variable at index n+1 cannot be loaded from. It can be stored into. However, doing so invalidates the
contents of local variable n.
The Java Virtual Machine does not require n to be even. In intuitive terms, values of types long and double need not be 64-bit aligned
in the local variables array.
Implementors are free to decide the appropriate way to represent such values using the two local variables reserved for the value.
The Java Virtual Machine uses local variables to pass parameters on method invocation. On class method invocation, any parameters
are passed in consecutive local variables starting from local variable 0. On instance method invocation, local variable 0 is always used to
pass a reference to the object on which the instance method is being invoked (this in the Java programming language). Any parameters
are subsequently passed in consecutive local variables starting from local variable 1.
Runtime Data Area
64. 64
// Compiled from LocalVariableSection.java (version 1.8 : 52.0, super bit)
public class LocalVariableSection {
// Method descriptor #6 ()V
// Stack: 1, Locals: 1
public LocalVariableSection();
0 aload_0 [this]
1 invokespecial java.lang.Object() [8]
4 return
Line numbers:
[pc: 0, line: 2]
Local variable table:
[pc: 0, pc: 5] local: this index: 0 type: LocalVariableSection
// Method descriptor #15 (ICJFLjava/lang/Object;DLjava/lang/String;BSZ)I
// Stack: 1, Locals: 13
public int testMethod(int a, char b, long c, float d, java.lang.Object e,
double f, java.lang.String g, byte h, short i, boolean j);
0 iconst_0
1 ireturn
Line numbers:
[pc: 0, line: 4]
Local variable table:
[pc: 0, pc: 2] local: this index: 0 type: LocalVariableSection
[pc: 0, pc: 2] local: a index: 1 type: int
[pc: 0, pc: 2] local: b index: 2 type: char
[pc: 0, pc: 2] local: c index: 3 type: long
[pc: 0, pc: 2] local: d index: 5 type: float
[pc: 0, pc: 2] local: e index: 6 type: java.lang.Object
[pc: 0, pc: 2] local: f index: 7 type: double
[pc: 0, pc: 2] local: g index: 9 type: java.lang.String
[pc: 0, pc: 2] local: h index: 10 type: byte
[pc: 0, pc: 2] local: i index: 11 type: short
[pc: 0, pc: 2] local: j index: 12 type: boolean
}
Stack Frame (5/7)
Local Variable Section (3/3)
Local Variable Section의 크기도 Compile-Time에 결정됨
Primitive Type은 실제 값이 저장되고, Object Type은 객체가 저장되는
Heap의 Reference가 저장
hidden this
0번 인덱스에 저장되는 reference형으로, 모든 Local Method, Instance Method
에 자동으로 추가되는 변수로, 여기에 저장된 reference를 통해 Heap에 있는
Class의 Instance 데이터를 찾아가는데 이용
static으로 선언한 Class Method의 경우에는 “hidden this” 레퍼런스가 존재하지
않음 Method Area에 저장됨
(샘플) Local Variable Section에서의 Method parameter
Runtime Data Area
class LocalVariableSection {
public int testMethod(int a,
char b,
long c,
float d,
Object e,
double f,
String g,
byte h,
short i,
boolean j) {
return 0;
}
}
index 선언 할당
0 reference hidden this
1 int int a
2 int int b
3
long long c
5 float float d
6 reference Object e
7
double double f
9 reference String g
10 int byte h
11 int short i
12 int boolean j
int -vs- Integer 어떤 자료형이 효율적일까?
Byte
Code
65. 65
Stack Frame (6/7)
Operand Stack
0-Base 배열로 구성
연산을 위해 사용되는 데이터 및 결과를 Operand Stack에 집어넣고 처리
① 하나의 instruction이 연산을 위해 Operand Stack에 값을 밀어 넣으면(Push)
② 다음 instruction에서는 이 값을 빼서 (Pop) 사용
③ 연산결과가 Operand Stack에 저장되어 지정된 곳으로 보내어 짐
Runtime Data Area
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Thread
Thread
JvM
Stack
Local Variable
Section
Operand Stack
Frame Data
Method Parameters
Local Variables
JVM의 Work Space
Constant pool Resolution
Normal Method Return
Exception Dispatch
66. 66
Stack Frame (7/7)
Operand Stack 데모
Runtime Data Area
자바 소스 Byte Code
public class OperandStack {
public void testMethod() {
int a, b, c;
a = 5;
b = 6;
c = a + b;
}
}
// Compiled from OperandStack.java (version 1.8 : 52.0, super bit)
public class OperandStack {
// Method descriptor #6 ()V
// Stack: 1, Locals: 1
public OperandStack();
0 aload_0 [this]
1 invokespecial java.lang.Object() [8]
4 return
Line numbers:
[pc: 0, line: 2]
Local variable table:
[pc: 0, pc: 5] local: this index: 0 type: OperandStack
// Method descriptor #6 ()V
// Stack: 2, Locals: 4
public void testMethod();
0 iconst_5
1 istore_1 [a]
2 bipush 6
4 istore_2 [b]
5 iload_1 [a]
6 iload_2 [b]
7 iadd
8 istore_3 [c]
9 return
Line numbers:
[pc: 0, line: 5]
[pc: 2, line: 6]
[pc: 5, line: 7]
[pc: 9, line: 8]
Local variable table:
[pc: 0, pc: 10] local: this index: 0 type: OperandStack
[pc: 2, pc: 10] local: a index: 1 type: int
[pc: 5, pc: 10] local: b index: 2 type: int
[pc: 9, pc: 10] local: c index: 3 type: int
}
67. 67
Stack Frame 메소드 수행 시뮬레이션 (1/10)
Runtime Data Area
public void testMethod() {
int a, b, c;
a = 5;
b = 6;
c = a + b;
}
0: iconst_5
1: istore_1
2: bipush 6
4: istore_2
5: iload_1
6: iload_2
7:
iadd
8: istore_3
9: return
store
load
상수 5를 Operand Stack에 PUSH
Operand Stack
PUSH
PUSH
POP
POP
명령 설명
iconst_n
iconst_n represents the series of opcodes iconst_0, iconst_1, iconst_2, iconst_3, iconst_4
and iconst_5.
These are used to push the constant ints 0 through 5 onto the stack.
istore_n
Pops an int off the stack and stores it in local variable n, where n is 0, 1, 2 or 3.
n must be a valid local variable number in the current frame.
bipush
bipush takes a single parameter, and pushes the resulting int value onto the operand
stack.
iload_n
iload_n represents the series of opcodes iload_0, iload_1, iload_2, and iload_3 that
retrieve a single precision float in local variables 0, 1, 2 or 3 and push it onto the stack.
iadd
Pops two integers from the operand stack, adds them, and pushes the integer result
back onto the stack.
return
return is used to return from a method whose return type is void.
All items on the current method's operand stack are discarded. If the current method is
marked as synchronized, then an implicit monitorexit instruction is executed. Then the
current method's frame is discarded, the invoker's frame is reinstated, and control
returns to the invoker.
Local Variables Section
ref hidden this
int a
int b
int c
0
1
2
3
5
68. 68
Stack Frame 메소드 수행 시뮬레이션 (2/10)
Runtime Data Area
public void testMethod() {
int a, b, c;
a = 5;
b = 6;
c = a + b;
}
0: iconst_5
1: istore_1
2: bipush 6
4: istore_2
5: iload_1
6: iload_2
7:
iadd
8: istore_3
9: return
store
load
Local Variable Section의 1번 인덱스에 값을 저장
Operand Stack
PUSH
PUSH
POP
POP
명령 설명
iconst_n
iconst_n represents the series of opcodes iconst_0, iconst_1, iconst_2, iconst_3, iconst_4
and iconst_5.
These are used to push the constant ints 0 through 5 onto the stack.
istore_n
Pops an int off the stack and stores it in local variable n, where n is 0, 1, 2 or 3.
n must be a valid local variable number in the current frame.
bipush
bipush takes a single parameter, and pushes the resulting int value onto the operand
stack.
iload_n
iload_n represents the series of opcodes iload_0, iload_1, iload_2, and iload_3 that
retrieve a single precision float in local variables 0, 1, 2 or 3 and push it onto the stack.
iadd
Pops two integers from the operand stack, adds them, and pushes the integer result
back onto the stack.
return
return is used to return from a method whose return type is void.
All items on the current method's operand stack are discarded. If the current method is
marked as synchronized, then an implicit monitorexit instruction is executed. Then the
current method's frame is discarded, the invoker's frame is reinstated, and control
returns to the invoker.
Local Variables Section
ref hidden this
int a
int b
int c
0
1
2
3
5
69. 69
Stack Frame 메소드 수행 시뮬레이션 (3/10)
Runtime Data Area
public void testMethod() {
int a, b, c;
a = 5;
b = 6;
c = a + b;
}
0: iconst_5
1: istore_1
2: bipush 6
4: istore_2
5: iload_1
6: iload_2
7:
iadd
8: istore_3
9: return
store
load
상수 6을 Openand Stack에 PUSH
Operand Stack
PUSH
PUSH
POP
POP
명령 설명
iconst_n
iconst_n represents the series of opcodes iconst_0, iconst_1, iconst_2, iconst_3, iconst_4
and iconst_5.
These are used to push the constant ints 0 through 5 onto the stack.
istore_n
Pops an int off the stack and stores it in local variable n, where n is 0, 1, 2 or 3.
n must be a valid local variable number in the current frame.
bipush
bipush takes a single parameter, and pushes the resulting int value onto the operand
stack.
iload_n
iload_n represents the series of opcodes iload_0, iload_1, iload_2, and iload_3 that
retrieve a single precision float in local variables 0, 1, 2 or 3 and push it onto the stack.
iadd
Pops two integers from the operand stack, adds them, and pushes the integer result
back onto the stack.
return
return is used to return from a method whose return type is void.
All items on the current method's operand stack are discarded. If the current method is
marked as synchronized, then an implicit monitorexit instruction is executed. Then the
current method's frame is discarded, the invoker's frame is reinstated, and control
returns to the invoker.
Local Variables Section
ref hidden this
int a
int b
int c
0
1
2
3
5
6
70. 70
Stack Frame 메소드 수행 시뮬레이션 (4/10)
Runtime Data Area
public void testMethod() {
int a, b, c;
a = 5;
b = 6;
c = a + b;
}
0: iconst_5
1: istore_1
2: bipush 6
4: istore_2
5: iload_1
6: iload_2
7:
iadd
8: istore_3
9: return
store
load
Local Variable Section 2번 인덱스에 6을 저장
Operand Stack
PUSH
PUSH
POP
POP
명령 설명
iconst_n
iconst_n represents the series of opcodes iconst_0, iconst_1, iconst_2, iconst_3, iconst_4
and iconst_5.
These are used to push the constant ints 0 through 5 onto the stack.
istore_n
Pops an int off the stack and stores it in local variable n, where n is 0, 1, 2 or 3.
n must be a valid local variable number in the current frame.
bipush
bipush takes a single parameter, and pushes the resulting int value onto the operand
stack.
iload_n
iload_n represents the series of opcodes iload_0, iload_1, iload_2, and iload_3 that
retrieve a single precision float in local variables 0, 1, 2 or 3 and push it onto the stack.
iadd
Pops two integers from the operand stack, adds them, and pushes the integer result
back onto the stack.
return
return is used to return from a method whose return type is void.
All items on the current method's operand stack are discarded. If the current method is
marked as synchronized, then an implicit monitorexit instruction is executed. Then the
current method's frame is discarded, the invoker's frame is reinstated, and control
returns to the invoker.
Local Variables Section
ref hidden this
int a
int b
int c
0
1
2
3
5
6
71. 71
Stack Frame 메소드 수행 시뮬레이션 (5/10)
Runtime Data Area
public void testMethod() {
int a, b, c;
a = 5;
b = 6;
c = a + b;
}
0: iconst_5
1: istore_1
2: bipush 6
4: istore_2
5: iload_1
6: iload_2
7:
iadd
8: istore_3
9: return
store
load
Local Variable Section 1번 인덱스의 값을 LOAD
Operand Stack
PUSH
PUSH
POP
POP
명령 설명
iconst_n
iconst_n represents the series of opcodes iconst_0, iconst_1, iconst_2, iconst_3, iconst_4
and iconst_5.
These are used to push the constant ints 0 through 5 onto the stack.
istore_n
Pops an int off the stack and stores it in local variable n, where n is 0, 1, 2 or 3.
n must be a valid local variable number in the current frame.
bipush
bipush takes a single parameter, and pushes the resulting int value onto the operand
stack.
iload_n
iload_n represents the series of opcodes iload_0, iload_1, iload_2, and iload_3 that
retrieve a single precision float in local variables 0, 1, 2 or 3 and push it onto the stack.
iadd
Pops two integers from the operand stack, adds them, and pushes the integer result
back onto the stack.
return
return is used to return from a method whose return type is void.
All items on the current method's operand stack are discarded. If the current method is
marked as synchronized, then an implicit monitorexit instruction is executed. Then the
current method's frame is discarded, the invoker's frame is reinstated, and control
returns to the invoker.
Local Variables Section
ref hidden this
int a
int b
int c
0
1
2
3
5
6
5
72. 72
Stack Frame 메소드 수행 시뮬레이션 (6/10)
Runtime Data Area
public void testMethod() {
int a, b, c;
a = 5;
b = 6;
c = a + b;
}
0: iconst_5
1: istore_1
2: bipush 6
4: istore_2
5: iload_1
6: iload_2
7:
iadd
8: istore_3
9: return
store
load
Local Variable Section 2번 인덱스의 값을 LOAD
Operand Stack
PUSH
PUSH
POP
POP
명령 설명
iconst_n
iconst_n represents the series of opcodes iconst_0, iconst_1, iconst_2, iconst_3, iconst_4
and iconst_5.
These are used to push the constant ints 0 through 5 onto the stack.
istore_n
Pops an int off the stack and stores it in local variable n, where n is 0, 1, 2 or 3.
n must be a valid local variable number in the current frame.
bipush
bipush takes a single parameter, and pushes the resulting int value onto the operand
stack.
iload_n
iload_n represents the series of opcodes iload_0, iload_1, iload_2, and iload_3 that
retrieve a single precision float in local variables 0, 1, 2 or 3 and push it onto the stack.
iadd
Pops two integers from the operand stack, adds them, and pushes the integer result
back onto the stack.
return
return is used to return from a method whose return type is void.
All items on the current method's operand stack are discarded. If the current method is
marked as synchronized, then an implicit monitorexit instruction is executed. Then the
current method's frame is discarded, the invoker's frame is reinstated, and control
returns to the invoker.
Local Variables Section
ref hidden this
int a
int b
int c
0
1
2
3
5
6
5
6
73. 73
Stack Frame 메소드 수행 시뮬레이션 (7/10)
Runtime Data Area
public void testMethod() {
int a, b, c;
a = 5;
b = 6;
c = a + b;
}
0: iconst_5
1: istore_1
2: bipush 6
4: istore_2
5: iload_1
6: iload_2
7:
iadd
8: istore_3
9: return
store
load
연산의 대상이 되는 Operand Stack의 값들을 모두 pop하여
Operand Stack
PUSH
PUSH
POP
POP
명령 설명
iconst_n
iconst_n represents the series of opcodes iconst_0, iconst_1, iconst_2, iconst_3, iconst_4
and iconst_5.
These are used to push the constant ints 0 through 5 onto the stack.
istore_n
Pops an int off the stack and stores it in local variable n, where n is 0, 1, 2 or 3.
n must be a valid local variable number in the current frame.
bipush
bipush takes a single parameter, and pushes the resulting int value onto the operand
stack.
iload_n
iload_n represents the series of opcodes iload_0, iload_1, iload_2, and iload_3 that
retrieve a single precision float in local variables 0, 1, 2 or 3 and push it onto the stack.
iadd
Pops two integers from the operand stack, adds them, and pushes the integer result
back onto the stack.
return
return is used to return from a method whose return type is void.
All items on the current method's operand stack are discarded. If the current method is
marked as synchronized, then an implicit monitorexit instruction is executed. Then the
current method's frame is discarded, the invoker's frame is reinstated, and control
returns to the invoker.
Local Variables Section
ref hidden this
int a
int b
int c
0
1
2
3
5
6
5
6
int형 값으로 더한 후 그 결과를 Operand Stack에 PUSH
11
74. 74
Stack Frame 메소드 수행 시뮬레이션 (8/10)
Runtime Data Area
public void testMethod() {
int a, b, c;
a = 5;
b = 6;
c = a + b;
}
0: iconst_5
1: istore_1
2: bipush 6
4: istore_2
5: iload_1
6: iload_2
7:
iadd
8: istore_3
9: return
store
load
Local Variable Section 3번 인덱스에 11을 저장
Operand Stack
PUSH
PUSH
POP
POP
명령 설명
iconst_n
iconst_n represents the series of opcodes iconst_0, iconst_1, iconst_2, iconst_3, iconst_4
and iconst_5.
These are used to push the constant ints 0 through 5 onto the stack.
istore_n
Pops an int off the stack and stores it in local variable n, where n is 0, 1, 2 or 3.
n must be a valid local variable number in the current frame.
bipush
bipush takes a single parameter, and pushes the resulting int value onto the operand
stack.
iload_n
iload_n represents the series of opcodes iload_0, iload_1, iload_2, and iload_3 that
retrieve a single precision float in local variables 0, 1, 2 or 3 and push it onto the stack.
iadd
Pops two integers from the operand stack, adds them, and pushes the integer result
back onto the stack.
return
return is used to return from a method whose return type is void.
All items on the current method's operand stack are discarded. If the current method is
marked as synchronized, then an implicit monitorexit instruction is executed. Then the
current method's frame is discarded, the invoker's frame is reinstated, and control
returns to the invoker.
Local Variables Section
ref hidden this
int a
int b
int c
0
1
2
3
5
6
11
75. 75
Stack Frame 메소드 수행 시뮬레이션 (9/10)
Runtime Data Area
public void testMethod() {
int a, b, c;
a = 5;
b = 6;
c = a + b;
}
0: iconst_5
1: istore_1
2: bipush 6
4: istore_2
5: iload_1
6: iload_2
7:
iadd
8: istore_3
9: return
store
load
method의 수행을 마치고 Stack Frame을 삭제
PUSH
PUSH
POP
POP
Operand Stack
명령 설명
iconst_n
iconst_n represents the series of opcodes iconst_0, iconst_1, iconst_2, iconst_3, iconst_4
and iconst_5.
These are used to push the constant ints 0 through 5 onto the stack.
istore_n
Pops an int off the stack and stores it in local variable n, where n is 0, 1, 2 or 3.
n must be a valid local variable number in the current frame.
bipush
bipush takes a single parameter, and pushes the resulting int value onto the operand
stack.
iload_n
iload_n represents the series of opcodes iload_0, iload_1, iload_2, and iload_3 that
retrieve a single precision float in local variables 0, 1, 2 or 3 and push it onto the stack.
iadd
Pops two integers from the operand stack, adds them, and pushes the integer result
back onto the stack.
return
return is used to return from a method whose return type is void.
All items on the current method's operand stack are discarded. If the current method is
marked as synchronized, then an implicit monitorexit instruction is executed. Then the
current method's frame is discarded, the invoker's frame is reinstated, and control
returns to the invoker.
Local Variables Section
ref hidden this
int a
int b
int c
0
1
2
3
5
6
11
76. 76
Stack Frame 메소드 수행 시뮬레이션 (10/10)
Runtime Data Area
class OperandStack{
public void testMethod() {
int a, b, c;
a = 5;
b = 6;
c = a + b;
}
}
public void operandStack();
Code:
0: iconst_5
1: istore_1
2: bipush 6
4: istore_2
5: iload_1
6: iload_2
7: iadd
8: istore_3
9: return
javap –c OperandStack
javap –c OperandStack
Operand
Stack
Local
Variable
Section
int c 3
int b 2
int a 1
hidden this 0
ref ref
5
ref
5
ref
5
6
ref
5
6
ref
5
6
5
ref
5
6
6
5
ref
5
6
13
ref
5
6
13
ref
iconst_5 istore_1 bipush 6 istore_2 iload_1 iload_2 istore_3
iadd return
Local
Variables
Section
Operand
Stack
load
store
PUSH
PUSH
POP
POP
77. 77
Stack Frame - Frame Data (1/3)
Constant Pool Resolution
Constant Pool의 Entry를 참조하기 위한 정보
Symbolic Reference Dynamic Reference로 변환하는 과정
java의 모든 reference는 Symbolic Reference이기 때문에 Resolution이 필요함.
Normal Method Return
Method를 호출한 stack frame으로 되돌아 가기 위해 pc register에 이
instruction의 pointer를 보관
반환 값이 있다면 다음 번 Current Frame(자신을 호출한 메소드의 Stack Frame
의 Operand Stack에 반환 값을 PUSH
Exception Dispatch
Exception이 발생하면 이를 핸들링하기 위해 Frame Data를 통해 Exception
Table을 참조
Frame Data에서 관리하는 Exception정보는 Exception Table에 대한 Reference
Exception이 발생하면 Exception Table을 참조하여 catch절에 해당하는 Bytecode
로 점프
Runtime Data Area
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Thread
Thread
JvM
Stack
Local Variable
Section
Operand Stack
Frame Data
78. 78
Stack Frame - Frame Data (2/3)
Constant Pool Resolution
Runtime Data Area
Constant Pool Resolution
Symbolic Reference Dynamic Reference 변환하는 과정
Symbolic Reference는 Method Area의
Constant Pool에 저장되어 있음
Constant Pool Resolution 결과 = Constant Pool Pointer
변수나 상수에 접근할 때
다른 Class를 참조할 때
Method를 수행할 때
특정 object가 특정 Class나 Interface에
의존관계가 있는지 확인할 때
Constant Pool Resolution 수행
79. 79
Stack Frame - Frame Data (3/3)
Exception Dispatch
Runtime Data Area
class JvmInternal2 {
public void operandStack() {
int a, b, c;
a = 5;
b = 6;
try {
c = a + b;
} catch (NullPointerException e){
c = 0;
}
}
}
public void operandStack();
Code:
0: iconst_5
1: istore_1
2: bipush 6
4: istore_2
5: iload_1
6: iload_2
7: iadd
8: istore_3
9: goto 16
12: astore 4
14: iconst_0
15: istore_3
16: return
Exception table:
from to target type
5 9 12 Class java/lang/NullPointerException
javap –c JvmInternal2
javap –c JvmInternal2
from
try 블록이 시작되는
bytecode의 entry number
to
try 블록이 끝나는
bytecode의 entry number
target
exception이 발생했을때 점
프해야할 entry number
type 정의한 exception
예외처리 절차
① try 블럭내에서 예외 발생 또는 throw
② exception 오브젝트의 type의 Class정보와 비교
③ Class정보와 일치하면 target으로 점프
④ Class정보와 일치하지 않으면, JVM은 Current Frame을
종료하고 이 메소드를 호출한 메소드의 Stack Frame에
이 exception을 다시 던져 처리를 반복
80. 80
Native Method Stack
Java Native Interface
Java는 JNI를 통해 native function을 호출하고 결과값을 받아 올 수 있다.
JVM은 native method를 위해 Native Method Stacks 메모리 공간을 마련하였다.
① 어플리케이션에서 native method를 수행
② Native Method Stacks에 새로운 Stack Frame을 생성하여 PUSH하고 native function을 수행
③ native method 수행이 끝나면, native method 를 수행한 java stack frame으로 돌아가는 것이 아니라 새로운 Stack Frame을 생성하여 다시 작업을 수행하게
된다.
Runtime Data Area
Java Stacks
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Stack Frame
Java Method 1
Java Method 2
Native Method 1
Native
Method
Stack
Native Function Call
81. 81
참고) Java Native Interface
JAVA 8 JNI Spec
https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html
자바와 자바 이외의 언어로 만들어진 애플리케이션이나 라이브러리가 상호 작용할 수 있도록 연결시켜 주는 인터페이스
Runtime Data Area
왜 JNI를 사용하는가?
JVM에서 지원되지 않은 특정 운영체제 서비스를 이용하고 싶을 때
자바의 클래스 라이브러리는 방대하고 다양한 서비스를 제공하지만, 특정 플랫폼
에서 제공하는 고유의 서비스의 기능을 모두 포함할 수는 없다. 특히, 특수한 목적
으로 제작된 하드웨어를 자바에서 제어해야 할 필요가 있다고 한다면, 자바만으로
해결하기는 힘들다.
Native Code(플랫폼에 종속적인 기계어 코드)로 개발된 함수를 이용하고 싶을 때
부하테스트 수행 시 3rd party가 개발한 보안 모듈 호출
자바에서 하드웨어 제어를 하고 싶을 때
기존의 프로그램(C/C++)에서 자바가 제공하는 서비스를 이용하고 싶을 때
기존에 작성된 프로그램이나 기존의 시스템(legacy)과의 연계 문제
82. 82
LAB) JNI를 이용한 Native Method 호출 (1/5)
구현 순서
Runtime Data Area
순서 작업 산출물
1 native method 프로토타입이 정의된 자바 소스 작성 HelloNative.java
2 자바 소스 컴파일 HelloNative.class
3 JNI-style header 파일 생성 HelloNative.h
4 native method를 구현한 C 소스파일 작성 HelloNative.c
5 C 소스파일을 compile하여 Native Library 생성 libHelloNative.so
6 HelloNative 자바 프로그램 실행
83. 83
LAB) JNI를 이용한 Native Method 호출 (2/5)
① native method 프로토타입이 정의된 자바 소스 작성
Runtime Data Area
native method 프로토타입이 정의된 자바 소스 작성
[root@jvmedu ~]# cd ~/lab/jni/ex01
[root@jvmedu ex01]# cat HelloNative.java
public class HelloNative {
private native void nativeMethod(int sleepSec); 함수 원형 정의
static {
System.loadLibrary(HelloNative);
}
nativeMethod() 가 구현된 라이브러리 로드
private void javaMethod(int sleepSec) {
System.out.println(javaMethod Called....);
this.nativeMethod(sleepSec);
}
네이티브 메소드 호출
public static void main(String[] args) throws Exception {
int sleepSec = Integer.parseInt(args[0]);
new HelloNative().javaMethod(sleepSec);
}
}
자바 메소드 호출
② 자바 소스 컴파일
HelloNative.java 파일을 컴파일하여 HelloNative.class 파일 생성
[root@jvmedu ex01]# javac HelloNative.java
[root@jvmedu ex01]# ls -l HelloNative.class
-rw-r--r-- 1 root root 781 Oct 20 23:21 HelloNative.class
84. 84
LAB) JNI를 이용한 Native Method 호출 (3/5)
③ JNI-style header 파일 생성
Runtime Data Area
javah 명령으로 이용하여 HelloNative.class에 정의된 native method에 대해 JNI-style의 헤더 파일 생성
[root@jvmedu ex01]# javah HelloNative
생성된 헤더 파일의 내용 확인
[root@jvmedu ex01]# cat HelloNative.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include jni.h
/* Header for class HelloNative */
#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern C {
#endif
/*
* Class: HelloNative
* Method: nativeMethod
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_HelloNative_nativeMethod
(JNIEnv *, jobject, jint);
nativeMethod() 함수 원형
#ifdef __cplusplus
}
#endif
#endif
85. 85
LAB) JNI를 이용한 Native Method 호출 (4/5)
④ native method를 구현한 C 소스파일 작성
Runtime Data Area
native method를 구현한 C 소스파일 작성
[root@jvmedu ex01]# vi HelloNative.c
HelloNative.c
#include jni.h
#include stdio.h
#include HelloNative.h
JNIEXPORT void JNICALL Java_HelloNative_nativeMethod(JNIEnv *env, jobject obj, jint sleepSec) {
printf(NativeMethod Called.....!n);
sleep(sleepSec);
return;
}
⑤ C 소스파일을 compile하여 Native Library 생성
gcc 컴파일러를 이용하여 HelloNative.c 를 compile하여 libHelloNative.so 공유 라이브러리 생성
[root@jvmedu ex01]# gcc HelloNative.c -o libHelloNative.so -shared -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux -fPIC
[root@jvmedu ex01]# file libHelloNative.so
libHelloNative.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked,
BuildID[sha1]=44fd5c90604df6023335a2211b4c39dd3fa797b3, not stripped
86. 86
LAB) JNI를 이용한 Native Method 호출 (5/5)
⑥ HelloNative 자바 프로그램 실행하고 visualvm으로 Thread Dump 생성 후 Native Stack 확인
Runtime Data Area
-Djava.library.path 옵션을 이용하여 HelloNative 자바 프로그램 실행
[root@jvmedu ex01]# java -Djava.library.path=. HelloNative 1000
javaMethod Called....
NativeMethod Called.....!
visualvm으로 Thread Dump 를 생성하고 main thread의 Stack Trace를 확인
Top Stack
-Djava.library.path 와 LD_LIBRARY_PATH 환경변수
native library를 찾을 위치 지정
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
- locked 0x00000000fd47b808 (a java.io.BufferedInputStream)
at java.io.FilterInputStream.read(FilterInputStream.java:83)
87. 87
Name 설명 비고
Young Generation
object가 생성되면 이 영역에 저장되었다가 시간이 지남에 따라
해제되지 않는 object들은 Old Generation으로 옮겨짐
Minor GC
Eden new 메소드로 object를 생성했을 때 가장 먼저 저장되는 영역
Survivor Alive객체를 저장하기 위한 영역 저장되는 영역
Old Generation Young 영역에서 저장되었던 객체 중에 오래된 객체가 이동되어서 저장되는 영역 Major GC
Permanent Generation
(Metaspace)
Class 메타정보, 메소드 실행 코드, Constant Pool등이 저장되는 영역
JVM Memory Layout
Runtime Data Area
Heap Space Method Area Native Area
Young Generation Old Generation Permanent Generation
(Metaspace - Java 8)
Code Cache
Eden
Survivor
Virtual
Tenured
Virtual
Rntime Constant Pool
Virtual
Thread 1..n
Compile
Native
Virtual
From To
Field Method Data
PC
Stack
Native
Stack
Code
-Xmn(Young Generation Size)
-Xms(Initial Heap Size)
-Xmx(Maximum Heap Size)
-XX:PermSize=n
88. 88
LAB) Native Out Of Memory (1/3)
LAB 개요
C언어로 개발한 Native Method에서 Native Heap에 1mbyte의 메모리를 사용하고 해제(free)하지 않을때 물리메모리를 100% 사용하고 SWAP
메모리도 100%를 다 소진하면 OS에 의해 Java 프로세스가 kill 되는 현상 관찰
Runtime Data Area
NativePmOom.jsp
%@ page language=java contentType=text/html; charset=UTF-8
pageEncoding=UTF-8%
%@ page import=com.jadecross.troubleshoot.oom.nativee.NativeLeak%
물리메모리 부족 데모 - 1회 호출시마다 1m 물리메모리 소진
%
NativeLeak.allocatePhysicalMemory();
%
NativeLeak.java
package com.jadecross.troubleshoot.oom.nativee;
public class NativeLeak {
public static native void allocatePhysicalMemory();
static {
System.loadLibrary(NativeLeak);
}
}
NativeLeak.c
#include jni.h
#include stdio.h
#include stdlib.h
#include memory.h
#include com_jadecross_troubleshoot_oom_nativee_NativeLeak.h
JNIEXPORT void JNICALL
Java_com_jadecross_troubleshoot_oom_nativee_NativeLeak_allocatePhysicalMemory(JNIEnv *env,
jclass classObj)
{
//printf(Allocated 1 mega bytesn);
int i = 0;
for (i; i1000; i++) {
char* bytes = (char*) malloc(1024);
strcpy(bytes,
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000);
}
//printf(t-- Used 1 mega bytesn);
return;
}
89. 89
LAB) Native Out Of Memory (2/3)
Runtime Data Area
① STS 실행후 Tomcat v8.5 서버 실행
[root@jvmedu ~]# sts
② visualvm을 실행하고 visualgc 플러그인 설치
Applications 뷰에서 Local Tomcat 더블 클릭 Visual GC 탭 클릭
[root@jvmedu ~]# visualvm
③ “System Monitor”를 실행하고 Resources 탭을 클릭하여 메모리 상황 관찰
[root@jvmedu ~]# gnome-system-monitor
90. 90
LAB) Native Out Of Memory (3/3)
Runtime Data Area
④ jadeedu_jvmswjava_toolapache-jmeter-5.4.1bin 폴더 하위의 jmeter.bat 파일 실행
⑤ 부하스크립트 파일 오픈 후 “UTG02_NatviePmOom” Thread Group을 Enable한 후 부하를 발생
시키고 메모리 관찰
스크립트 파일 : jadeedu_jvmswjava_toolapache-jmeter-5.4.1jmxJvmTroubleshoot.jmx
Enable Thread Group : UTG02_NatviePmOom
부하 발생
8080
192.168.56.96
91. 91
Method Area
Class
Data
Class
Data
Class
Data
Class
Data
Class
Data
Class
Data
Class
Data
Class
Data
Method Area
ClassLoader에 의해 Load된 모든 Type의 메타 정보를 저장하는 메모리 공간
Class file에서 type에 관한 메타 정보를 추출하여 Method Area에 저장
Bytecode, 모든 변수, 상수, Reference, Method Data
Class variable, Class method
생성자 정보
JVM이 시작할 때 생성된 GC의 대상
모든 Thread들에 공유
Class file에서 type에 관한 메타 정보를 추출하여 Method Area에 저장
ClassLoader에게 넘겨 받은 Class File 에서 Type 관련 정보를 추출하여 저장
Method Area의 구현은 Vendor의 재량
Hotspot JVM
– JDK7 까지는 Permanent Area로 명명하여 Generation Heap의 한 영역으로 포함
– JDK8 이상에서는 MetaSpace로 명명되었고 Native Memory 사용
IBM에서는 Heap내에 별도의 구분 없이 Class Object 형태로 저장
Runtime Data Area
Thread
Thread Thread
Thread
Thread
Thread
92. 92
LAB) Bytecode 관찰
Bytecode viewer 설치
C:jadeedu_jvmswjava_toolbytecode_viewerjclasslib_win64_5_5.exe
Bytecode viewer 실행 후 Product.class 파일 열기
Product.class 파일 위치 : C:jadeedu_jvmswlabbytecodeProduct.class
Runtime Data Area
Product.java
package org.mybatis.jpetstore.domain;
import java.io.Serializable;
public class Product implements Serializable {
private static final long serialVersionUID = -7492639752670189553L;
private String productId;
private String categoryId;
private String name;
private String description;
public String getProductId() { return productId; }
public void setProductId(String productId) { this.productId = productId.trim(); }
public String getCategoryId() { return categoryId; }
public void setCategoryId(String categoryId) { this.categoryId = categoryId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
@Override
public String toString() { return getName(); }
}
93. 93
Class metadata in Method Area (1/7)
Type Information
Type의 전체 이름
package.class 형태 : Fully Qualified Name
Type의 직계 Superclass의 전체이름
Type이 Interface이거나 java.lang.Object Class이거나 SuperClass가 없으면 제외
Type이 Class인지 Interface인지의 여부
Type의 modifier (public, abstract, final)
Interface의 경우 직접 Link되고 있는 객체의 리스트 (참조 순서대로)
Runtime Data Area
Class metadata
in
Method Area
Type Information
Constant Pool
Field Information
Method Information
Class Variables
Reference to class ‘ClassLoader'
Reference to Class class
94. 94
Class metadata in Method Area (2/7)
Constant Pool
Constant Pool은 Type에서 사용된 Constant의 Ordered Set임
Literal Constant, Type, Field, Method로의 Symbolic Reference가
포함됨
Constant Pool의 Entry는 Array처럼 index로 접근
Type에서 사용되는 모든 Type, Method, Field로의 Symbolic
Reference는 Dynamic Linking의 핵심 요소임
Runtime Data Area
Class metadata
in
Method Area
Type Information
Constant Pool
Field Information
Method Information
Class Variables
Reference to class ‘ClassLoader'
Reference to Class class
95. 95
Class metadata in Method Area (3/7)
Field Information
Type에서 선언된 모든 Field의 정보가 순서대로 저장되는 장소
Field 이름
Member Variable, Class Variable 을 의미
Field의 Data Type, 선언된 순서
Field Modifier
public, private, protected, static, final, volatile, transient
Runtime Data Area
Class metadata
in
Method Area
Type Information
Constant Pool
Field Information
Method Information
Class Variables
Reference to class ‘ClassLoader'
Reference to Class class
참고) Field와 Variable
Java 에는 4가지 종류의 변수가 있는데, 그것은 각각 Instance Variable, Class Variable, Local Variable, Parameter이다.
이중 Field라 함은 Instance Variable과 Class Variable을 의미한다.
이들은 각각 non-static field, static field로 표현되기도 한다.
그리고 나머지 Local Variable과 Parameter Variable은 각각 Method에 속하는 것으로 Field와 이들을 포함하여 Variable이라고 한다.
96. 96
Class metadata in Method Area (4/7)
Method Information
Method 이름
Method의 Return Type (or void)
Method Parameter수와 Data Type (순서대로)
Method Modifier
public, private, protected, static, final, syncronized, native, abstract
Runtime Data Area
Class metadata
in
Method Area
Type Information
Constant Pool
Field Information
Method Information
Class Variables
Reference to class ‘ClassLoader'
Reference to Class class
native 또는 abstract 메소드가 아니라면 다음
의 정보가 추가됨
Method의 ByteCode
Method Stack Frame의 Operand Stack 및 Local
variable Section의 크기
Exception Table
97. 97
Class metadata in Method Area (5/7)
Class Variables
Class 변수 = Static 변수
모든 instance에 공유되며 Instance가 없어도 접근이 가능
이 변수는 Instance의 것이 아니라 Class에 속함
Class를 사용하기 이전에 이 변수들은 미리 메모리를 할당 받아 놓아야 함
final로 선언할 경우에는 이를 변수로 취급하는 것이 아니라 상수로 취급하여
Constant Pool의 Literal Constant로 저장된다.
Runtime Data Area
Class metadata
in
Method Area
Type Information
Constant Pool
Field Information
Method Information
Class Variables
Reference to class ‘ClassLoader'
Reference to Class class
Class
Instance
Instance
Instance
Instance
Class Variable
98. 98
Class metadata in Method Area (6/7)
Reference to class ‘ClassLoader’
하나의 Type이 다른 Type을 참조할 때 JVM은 같은 ClassLoader를 사용
이런 이유로 Type의 Classloader정보가 필요
User-Defined Classloader인 경우만 reference를 저장
Bootstrap Classloader의 경우는 null
JVM이 Dynamic Linking시 이 정보를 이용하여 참조하는 Class를 같은
Classloader를 통해 Load
ClassLoader 종류
Bootstrap ClassLoader
User-defined ClassLoader
Runtime Data Area
Class metadata
in
Method Area
Type Information
Constant Pool
Field Information
Method Information
Class Variables
Reference to class ‘ClassLoader’
Reference to Class class
Reference ClassLoader class
99. 99
Class metadata in Method Area (7/7)
Reference to Class class
각 Data Type이 load될 때 마다 java.lang.class의 instance가 하나씩 생성
getClass(), forClass(), isInterface() 등의 Method를 호출할 때 이 Reference를
통해 값을 반환
Runtime Data Area
Class metadata
in
Method Area
Type Information
Constant Pool
Field Information
Method Information
Class Variables
Reference to class ‘ClassLoader’
Reference to Class class
Reference java.lang.Class class
101. 101
① STS 실행후 Tomcat v7.0 서버 실행
[root@jvmedu ~]# sts
② visualvm을 실행하고 visualgc 플러그인 설치
Applications 뷰에서 Local Tomcat 더블 클릭 Visual GC 탭 클릭
[root@jvmedu ~]# visualvm
③ “System Monitor”를 실행하고 Resources 탭을 클릭하여 메모리 상황 관찰
[root@jvmedu ~]# gnome-system-monitor
LAB) Method Area Out Of Memory (2/6)
Runtime Data Area
Permgen
102. 102
LAB) Method Area Out Of Memory (3/6)
Runtime Data Area
④ jadeedu_jvmswjava_toolapache-jmeter-5.4.1bin 폴더 하위의 jmeter.bat 파일 실행
⑤ 부하스크립트 파일 오픈 후 “UTG04_Permgen(Metaspace) OOM” Thread Group을 Enable한 후 부하를 발생시키고 메모리 관찰
스크립트 파일 : jadeedu_jvmswjava_toolapache-jmeter-5.4.1jmxJvmTroubleshoot.jmx
Enable Thread Group : UTG04_Permgen(Metaspace) OOM
부하 발생
7080
192.168.56.96
104. 104
Java 7 Java 8
LAB) Method Area Out Of Memory (5/6)
Java8 Metaspace
Java7의 Permgen 영역은 Native memory 영역으로 이동하여 Metaspace영역으로 명명되었으며, 다만 static object는 Heap영역으로 옮겨
져서 GC의 대상이 최대한 될 수 있도록 하였다.
Runtime Data Area
https://blog.voidmainvoid.net/210
상기 Java 8의 memory 구조를 보면 알 수 있듯이 Metaspace가
Native Memory를 이용함으로써 java application이 필요한 만큼
계속해서 늘어나는 특징이 있다. 상기 옵션을 통해 알 수 있듯이,
Java 8의 MaxMetaspaceSize는
18,446,744,073,709,547,520Byte(약 16ExaByte, 64bit 프로세서
최고 메모리 상한치)라는 것을 알 수 있다.
그러므로, Java 8의 -XX:MaxMetaspaceSize를 두지 않는 이상,
Native memory 자원을 최대한 사용한다.
Metaspace 옵션 설정
-XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m
106. 106
Java Heap
Heap
Instance나 Array가 저장되는 공간으로 모든 Thread들에 공유
JVM은 Heap에 메모리를 할당하는 instruction만 존재
new, newarray, anewarray, multianewarray
메모리 해제를 위한 명시적인 java code나 byte code도 없으며, 메모리의 해제는 Garbage Collection를 통해 수행됨
Java Heap의 구현은 Vendor의 재량
각 JVM Vendor마다 Heap의 구조 및 Garbage Collection, Garbage Collector의 구현이 다름
참고) new Bytecode
Runtime Data Area
JVM
Java Heap
Object
Instance
Data
Class
Pointer
Array
Thread
Thread Thread
Thread
Thread
Thread
new : create an object
Description
new is used to create object instances.
new takes a single parameter, class, the name of the class of object you want to
create. class is resolved into a Java class (see Chapter 7 for a discussion of how
classes are resolved). Then new determines the size in bytes of instances of the given
class and allocates memory for the new instance from the garbage collected heap. The
fields of the instance are set to the initial value 0 (for numeric and boolean fields),
or null (for reference fields). Next, a reference to the new object is pushed onto the
operand stack.
Note that the new object is initialize uninitialized - before the new object can be used,
one of its init methods must be called using invokespecial, as shown in the example
below.
Exceptions
• OutOfMemoryError - not enough memory to allocate a new instance
• InstantiationError - The class named by type is an abstract class or an interface
Share
107. 107
Heap Space Method Area Native Area
Young Generation Old Generation Permanent Generation
(Metaspace - Java 8)
Code Cache
Eden
Survivor
Virtual
Tenured
Virtual
Rntime Constant Pool
Virtual
Thread 1..n
Compile
Native
Virtual
From To
Field Method Data
PC
Stack
Native
Stack
Code
-Xmn(Young Generation Size)
-Xms(Initial Heap Size)
-Xmx(Maximum Heap Size)
-XX:PermSize=n
JVM의 Memory - Heap
Generational Heap
Runtime Data Area
Name 설명 비고
Young Generation
object가 생성되면 이 영역에 저장되었다가 시간이 지남에 따라
해제되지 않는 object들은 Old Generation으로 옮겨짐
Minor GC
Eden new 메소드로 object를 생성했을 때 가장 먼저 저장되는 영역
Survivor Alive객체를 저장하기 위한 영역 저장되는 영역
Old Generation Young 영역에서 저장되었던 객체 중에 오래된 객체가 이동되어서 저장되는 영역 Major GC
Permanent Generation
(Metaspace)
Class 메타정보, 메소드 실행 코드, Constant Pool등이 저장되는 영역
108. 108
LAB) 디폴트 힙 사이즈 확인
Java5부터 자동으로 Garbage Collector, Heap Size등을 자동으로 선택
Hardware Resource와 OS정보가 기준
Sever Class와 Client Class의 구분
-XX:+PrintCommandLineFlags
This option prints all command-line flags to the VM
Runtime Data Area
Version 디폴트 Command Line Flags
JAVA 7
[root@jvmedu ~]# /opt/java/jdk7/bin/java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=64717248 -XX:MaxHeapSize=1035475968 -XX:+PrintCommandLineFlags -XX:+UseCompressedOops -
XX:+UseParallelGC
java version 1.7.0_80
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)
JAVA 8
[root@jvmedu ~]# /opt/java/jdk8/bin/java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=64717248 -XX:MaxHeapSize=1035475968 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers
-XX:+UseCompressedOops -XX:+UseParallelGC
openjdk version 1.8.0_302
OpenJDK Runtime Environment (Temurin)(build 1.8.0_302-b08)
OpenJDK 64-Bit Server VM (Temurin)(build 25.302-b08, mixed mode)
110. 110
① STS 실행후 Tomcat v8.5 서버 실행
[root@jvmedu ~]# sts
② visualvm을 실행하고 visualgc 플러그인 설치
Tools Plugins Available Plugins Visual GC Install
[root@jvmedu ~]# visualvm
LAB) visualvm을 이용한 JVM 메모리 이해 (1/2)
visualgc 플러그인
Runtime Data Area
③ Applications 뷰에서 Local Tomcat 더블 클릭 Visual GC 탭 클릭
111. 111
④ jadeedu_jvmswjava_toolapache-jmeter-5.4.1bin 폴더 하위의 jmeter.bat 파일 실행
⑤ 부하스크립트 파일 오픈 후 “START”버튼을 클릭하여 부하를 발생시키고 visualvm에서 JVM
메모리 변화를 관찰
스크립트 파일 : jadeedu_jvmswjava_toolapache-jmeter-5.4.1jmxjpetstore.jmx
LAB) visualvm을 이용한 JVM 메모리 이해 (2/2)
JVM 메모리 관찰
Runtime Data Area
부하 발생
192.168.56.96
112. 112
LAB) java.lang.OutOfMemoryError: Java heap space (1/5)
LAB) 개요
Http Request 1번마다 Member 인스턴스를 1개 생성하고 application 객체(Global 객체, 모든 Thread가 공유)의 ArrayList에 추가하여 Heap
Memory 부족해지는 것을 관찰
Runtime Data Area
HeapOom.jsp
%@ page language=java contentType=text/html; charset=UTF-8
pageEncoding=UTF-8%
%@ page import=java.util.*%
%@ page import=com.jadecross.troubleshoot.oom.heap.Member%
Heap 메모리 부족 데모
%
/*
* Http 요청 1건마다 Member객체를 ArrayList에 추가
*/
ArrayListMember members;
members = (ArrayListMember) application.getAttribute(members);
if (members == null) {
members = new ArrayListMember();
application.setAttribute(members, members);
}
members.add(new Member());
%
Member.java
public class Member implements Serializable {
public String name;
public String age;
public String sex;
public String address;
public Member() {
this.name = name_ + UUID.randomUUID().toString();
this.age = age_ + UUID.randomUUID().toString();
this.sex = sex_ + UUID.randomUUID().toString();
this.address = address_ + UUID.randomUUID().toString();
}
}
113. 113
LAB) java.lang.OutOfMemoryError: Java heap space (2/5)
Runtime Data Area
① STS 실행후 Tomcat v7.0 서버 실행
[root@jvmedu ~]# sts
② visualvm을 실행하고 visualgc 플러그인 설치
Applications 뷰에서 Local Tomcat 더블 클릭 Visual GC 탭 클릭
[root@jvmedu ~]# visualvm
③ “System Monitor”를 실행하고 Resources 탭을 클릭하여 메모리 상황 관찰
[root@jvmedu ~]# gnome-system-monitor
Permgen
114. 114
LAB) java.lang.OutOfMemoryError: Java heap space (3/5)
Runtime Data Area
④ jadeedu_jvmswjava_toolapache-jmeter-5.4.1bin 폴더 하위의 jmeter.bat 파일 실행
⑤ 부하스크립트 파일 오픈 후 “UTG05_Heap OOM” Thread Group을 Enable한 후 부하를 발생시키고 Heap 메모리 관찰
스크립트 파일 : jadeedu_jvmswjava_toolapache-jmeter-5.4.1jmxJvmTroubleshoot.jmx
Enable Thread Group : UTG05_Heap OOM
부하 발생
7080
192.168.56.96