2. JVM 구조
클래스 로더 시스템
- .class 에서 바이트코드를 읽고 메모리에 저장
- 로딩 : 클래스를 읽어오는 과정
- 링크 : 레퍼런스를 연결하는 과정
- 초기화 : static 값들 초기화 및 변수에 할당
// 위와 같이 static 변수를 초기화하는 과정이 ClassLoader에서 진행된다.
static String myName = "hyun6ik";
메모리
- 메소드 영역에는 클래스 수준의 정보 (클래스 이름, 부모 클래스 이름, 메소드, 변수) 저장한다. 공유 자원이다.
- 힙 영역에는 객체를 저장. 공유 자원이다.
- 스택 영역에는 쓰레드마다 런타임 스택을 만들고, 그 안에 메소드 호출을 스택프레임이라 부르는 블럭으로 쌓난다. 쓰레드가 종료하면 런타임 스택도 사라진다.
- PC(Program Counter) 레지스터 : 쓰레드 마다 쓰레드 내 현재 실행할 스택 프레임을 가리키는 포인터가 생성된다.
- 네이티브 메소드 스택
메소드 영역
- 패키지 명을 포함한 클래스의 이름 (com.example.thejava.App)
- 부모 클래스 이름 (Object)
- 메소드 이름 (work, main)
- 변수 이름 (foo)
모두 메소드 영역에 저장이 되고 공유되는 자원이 된다. 즉 다른 영역에서도 참조할 수 있는 자원들이다.
힙 영역
App app = new App();
스택 영역
- 에러메세지를 볼 때 메소드가 쭉 쌓여있는 것을 볼 수 있는데 이것이 바로 에러메시지가 스택 영역에 쌓여 있는 모습이다.
- 스택 영역은 공유자원이 아니기 때문에 쓰레드 마다 하나씩 만들어진다.
실행 엔진
- 인터프리터 : 바이트코드를 한줄씩 실행
- JIT 컴파일러 : 인터프리터 효율을 높이기 위해, 인터프리터가 반복되는 코드를 발견하면 JIT 컴파일러로 반복되는 코드를 모두 네이티브 코드로 바꿔둔다. 그 다음부터 인터프리터는 네이티브코드로 컴파일된 코드를 바로 사용한다.
- GC(Garbage Collector) : 더이상 참조되지 않는 객체를 모아서 정리한다.
JNI(Java Native Interface)
- 자바 애플리케이션에서 C,C++, 어셈블리로 작성된 함수를 사용할 수 있는 방법을 제공한다.
- Native 키워드를 사용한 메소드 호출
네이티브 메소드 라이브러리
- C, C++로 작성된 라이브러리
- JNI를 통해서 사용가능하다.
요약
- Java 파일을 ClassLoader가 읽어서 메모리 영역의 힙,메소드 영역에 용도에 따라 알맞게 배치한다. 그리고 나서 실행엔진 (인터프리터 JIT 컴파일러)을 통해 실행을 해서 쓰레드가 만들어지면 각각의 쓰레드마다 스택,PC,Native Method Stack 영역이 만들어진다.
- 실행 엔진은 한줄씩 바이트 코드를 읽으면서 실행하는데 반복되는 코드는 JIT 컴파일러를 사용하고 메모리 최적화를 위해 GC또한 사용한다.
- 또한 메모리나 실행엔진이 Native 라이브러리를 사용할려면 JNI를 이용한다.