학습할 것
- JVM이란 무엇인가
- 컴파일 하는 방법
- 실행하는 방법
- 바이트코드란 무엇인가
- JIT 컴파일러란 무엇이며 어떻게 동작하는지
- JVM 구성 요소
- JDK와 JRE의 차이
- javac 옵션 조사
학습한 내용
1. JVM이란 무엇인가
- 스택 기반의 자바 가상머신 ( cf. ARM 아키텍처 같은 하드웨어는 레지스터 기반으로 동작 )
- JVM ( java virtual machine ) 은 자바 애플리케이션을 클래스 로더를 통해 읽어들여 자바 API 와 함께 실행한다.
- == 자바 바이트코드, .class 파일을 실행할 수 있는 주체이다.
- 어떤 OS 이던지 자바 코드를 실행할 수 있다. (JAVA 와 OS 사이 중개자 역할 수행)
- Garbage Collection 이 있어서 개발자가 메모리 할당, 해제를 신경 안써도 된다.
추가) 자바 프로그램의 실행 과정
- 프로그램이 실행되면 JVM 은 OS 로부터 이 프로그램이 필요로 하는 메모리를 할당받는다. JVM 은 이 메모리를 용도에 따라 여러 영역으로 나눠 관리한다.
- 자바 컴파일러(javac) 가 자바 소스코드(.java) 를 읽어 자바 바이트코드(.class)로 변환시킨다.
- 클래스로더를 통해 class 파일들을 JVM로 로딩한다.
- 로딩된 class 파일들은 Execution engine 을 통해 해석된다.
- 해석된 class 파일들은 runtime Data Areas 에 배치되어 실질적 수행이 이뤄진다.
- 이 과정속에서 JVM 은 필요에 따라 Thread Synchronization 갗ㅌ은 GC 같은 관리 작업을 수행한다.
2. 컴파일 하는 방법
javac helloWorld.java
3. 실행하는 방법
( 14버전으로 컴파일하고, 8버전에서 실행하려면 옵션을 넣어 줘야하고, 8버전으로 컴파일 하고, 14버전에서 실행은 가능하다.)
java helloWorld.class
java helloWorld
4. 바이트코드란?
특정 하드웨어가 아닌 가상 컴퓨터에서 돌아가는 실행 프로그램을 위한 이진표현법/ 하드웨어가 아닌 소프트웨어에 의해 처리되어 기계어보다는 더 추상적이다.
이러한 자바 코드는 자바컴파일러에 의해 아래와 같은 바이트코드로 번역된다.
for (int i = 2; i < 1000; i++) {
for (int j = 2; j < i; j++) {
if (i % j == 0)
continue outer;
}
System.out.println (i);
}
0: iconst_2
1: istore_1
2: iload_1
3: sipush 1000
6: if_icmpge 44
9: iconst_2
10: istore_2
11: iload_2
12: iload_1
13: if_icmpge 31
16: iload_1
17: iload_2
18: irem
19: ifne 25
22: goto 38
25: iinc 2, 1
28: goto 11
31: getstatic #84; // Field java/lang/System.out:Ljava/io/PrintStream;
34: iload_1
35: invokevirtual #85; // Method java/io/PrintStream.println:(I)V
38: iinc 1, 1
41: goto 2
44: return
5. JIT 컴파일러의 개념과 동작 방식
Interpreter(인터프리터)
실행 엔진은 자바 바이트코드를 명령어 단위로 읽어서 실행한다. 하지만, 이 방식은 한 줄씩 수행하기 때문에 느리다.
JIT(Just-In-Time)
안터프리터 방식의 단점을 보완하기 위해 도입된 것이 JIT 컴파일러이다. 인터프리터 방식으로 실행하다가 적절한 시점에 바이트코드 전체를 컴파일해서 네이티브코드로 변경하고, 이 후, 더이상 인터프리팅하지 않고, 네이티브코드로 직접 실행하는 방식이다. 네이티브 코드는 캐기에 보관하기 때문에, 한 번 컴파일된 코드는 빠르게 수행한다.
처음 작동하는데 시간이 오래걸리므로, 한번만 실행되는 코드라면 컴파일 안하고, 인터프리팅하는 것이 유리하다.
따라서 JIT 컴파일러를 사용하는 JVM 들은 내부적으로 해당 메소드가 얼마나 자주 수행되는지 체크해, 역치가 넘으면 컴파일을 수행한다.
6. JVM 구성요소
JVM 은 스택 기반의 가상 머신으로 메소드에서 호출되는 대다수의 명령어가 스택에서 피연산자를 택하고, 연산 후 다시 결과를 스택에 저장하는 방식을 취한다.
- JVM 메모리 영역에 대한 설명
- method 영역: 메소드와 클래스 변수를 저장하기 위한 공간, 모든 프로그램에게 공유
- heap area: 사용자가 생성하는 java object 들이 저장되는 공간. 동적으로 할당되어 사용된다.
- stack area: 메소드 호출시, 해당 메소드의 매개변수, 지역 변수, 임시 변수 등을 저장하기 위한 stack 구조의 메모리이다.
- native heap area: java object 가 아닌 native object 들이 거주하는 공간. os 에서 결정/
- permanent space: class 에 대한 meta 정보를 저장하는 공간. ( permanent space 는 java heap 의 하위 영역)
7. JDK 와 JRE 의 차이
요즘은 합쳐진 형태로 나온다.
JDK와 JRE의 차이점은 JDK는 Java 용 소프트웨어 개발 키트이고 JRE는 프로그램을 실행하는 장소이다.
8. javac 옵션 조사
javac [ options ] [ sourcefiles ] [ @argfiles ]
옵션명 | 설명 |
-classpath classpath | 컴파일러가 컴파일 하기 위해서 필요로 하는 참조할 클래스 파일들을 찾기 위해서 컴파일시 파일 경로를 지정해주는 옵션 |
-d | 클래스 파일의 출력처 디렉토리를 설정 |
-encoding encoding | 원시 파일의 인코딩명 (EUC-JP 나 UTF-8 등)을 지정 |
-target version | taeget [자바 버전] 지정된 버전의 VM 상에서 동작하는 클래스 파일을 생성 예) 1.4 JDK 1.4 이후의 VM 상에서는 동작하지만, 1.1, 1.2, 및 1.3 의 VM 상에서는 동작하지 않는 클래스 파일을 생성합니다. |
-g | 모든 디버깅 정보를 생성 -g:none: 디버깅 정보를 전혀 생성 시키지 않는다. -g:{lines, vars, source}: 위처럼 명시적으로, 몇몇 디버깅 정보를 생성 lines은 라인정보, vars는 지역변수, sounce는 소스 파일 정보를 나타냄 |
-nowarn | 경고메시지 생성 x |
-verbose | 컴파일러와 링커가 현재 어느 소스파일들이 컴파일 되고, 어떤 파일이 링크되고 있는지 출력함. |
-deprecation | 소스 코드 내에서 사용된 deprecated api 의 위피를 출력함. |
-bootclasspath path |
특정한 bootstrap또는 확장 클래스를 지정 |
-extdirs 디렉터리 |
특정한, 확장 디렉토리를 지정한다.cross-compiling시 주로, 사용되어지는 옵션 |
참고 문헌
www.youtube.com/watch?v=peEXNN-oob4&t=27s (백기선님 자바 스터디)
ko.wikipedia.org/wiki/%EC%9E%90%EB%B0%94_%EB%B0%94%EC%9D%B4%ED%8A%B8%EC%BD%94%EB%93%9C
blog.naver.com/PostView.nhn?blogId=minsuk0123&logNo=44865799
'스프링, 자바' 카테고리의 다른 글
타임리프 찾아본 로그 (0) | 2020.11.16 |
---|---|
자바 데이터 타입, 변수 그리고 배열 (0) | 2020.11.15 |
클린 코드 리팩터링 공부하고 싶을때 (0) | 2020.11.06 |
spring security (0) | 2020.11.05 |
타임리프 공부중.. (0) | 2020.10.28 |