JVM (java virtual machine)
- JAVA는 OS에 종속적이지 않다. 그 이유는 OS위에서 JVM이 시작되고, 이 JVM이 Java를 실행시키기 때문이다.
- JVM이 인식할 수 있는 java byteCode로 변환된다. bytecode는 기계어가 아니기때문에 OS에서 바로 실행되지 않는다.
- JVM이 각각의 OS가 byteCode를 이해 할 수있도록 해석한 파일을 준다. 따라서 OS에 종속적이지 않고, Java 파일 하나만 만들면 어느 OS가 돼든 JVM위에서 실행 할 수 있다.
JIT(just in time compliation)
- 바이트 코드는 실시간 번역기 또는 JIT 컴파일러에 의해 바이너리 코드로 변환된다. (기계어나 비트라고 하는 것)
- JIT -> 바이너리 코드란? 이진코드 or 바이너리 코드. 컴퓨터가 인식할 수 있는 0과 1로 구성된 코드.
- 인터프리터 방식과 컴파일러 방식을 혼합하여 사용한다.
장점
- 메모리 사용량을 감소 시킨다.
- 실행 시점에서 인터프리터 방식으로 기계어 코드를 실행, 그 코드를 캐싱하여 같은 함수가 여러번 호출될 때 매번 기계어 코드를 생성하는 것을 방지한다.
- 프로그램 시작 후 JIT 컴파일러가 실행되며 코드 최적화는 코드를 실행하는 동안 수행할 수 있습니다.
단점
- 프로그램이 처음 실행될 때 인터프리터 방식으로 실행되기 때문에 초기 실행 속도가 느립니다.
- JIT 컴파일러가 동작하는 동안 메모리 사용량이 증가합니다.
JVM의 구성요소
클래스 로더(Class Loader) : 클래스 파일을 읽어들여 JVM 내부로 로드합니다.
실행 엔진(Execution Engine) : 클래스 로더가 로드한 바이트 코드를 실행합니다.
인터프리터(Interpreter) : 바이트 코드를 한 줄씩 읽어들여 해석하고 실행합니다.
JIT 컴파일러(Just-in-Time) : 인터프리터 방식으로 실행되는 것을 개선하기 위해 바이트 코드를 네이티브 코드로 컴파일합니다.
가비지 콜렉터(Garbage collector) : 더 이상 사용하지 않는 객체를 자동으로 제거합니다.
런타임 데이터 영역(Runtime Data Area) : JVM이 프로그램을 수행하기 위해 할당받은 메모리 영역입니다.
JVM의 메모리
Meathod Area, Heap Area, Stack Area와 Pc Register, Native Method Stack으로 나뉜다.
1. Meathod Area (class area, static area)
- 런타임시 생성된 모든 스레드가 공유하는 영역.
- 각각의 클래스와 인터페이스에 대한 런타임 상수 풀, 필드와 메서드 정보, Static 변수, 메서드의 바이트코드 등을 보관합니다
- 클래스 로더가 클래스와 인터페이스의 메타 데이터를 로드할 때 Method Area에 적재한다.
2. Heap area
- 모든 스레드가 공유하는 영역.
- 객체를 저장하는 가상메모리 공간, new 연산자로 생성되는 객체와 배열을 저장한다.
- Heap에 저장된 객체나 배열은 다른 객체의 필드나 Stack 영역의 변수에 의해 참조 될 수 있다.
- Heap은 프로그램이 종료 될 때 까지 메모리에 남아 있다.
- Heap에 할당된 메모리는 GC에 의해 자동으로 관리 된다.
3. Stack area
- Stack Area는 메서드 호출 시마다 각각의 스택 프레임이 생성되며 지역변수와 파라미터 등이 저장됩니다
- 프로그램 실행과정에서 임시로 할당되었다가 메소드가 빠져나가면 바로 소멸되는 특성의 데이터를 저장하기 위한 영역.
- Stack (FILO) 선입후출 형태. 각종 형태의 변수나 임시 데이터, 스레드나 메소드의 정보를 저장한다.
4. 기타
- pc register : Thread가 시작될 때 생성되며, Thread 하나당 한개씩 만들어진다. 현재 Thread가 실행되는 부분의 주소와 명령을 저장한다.
- native method stack : Low level code(기계어)로 작성된 프로그램을 실행 시키는 영역
- MetaSpace(Permanent Genertaion) - 클래스 로딩시 클래스 정보를 저장하는 공간.