Java Virtual Machine
OS에 독립적, Java Byte code 해석 및 실행 역할

CPU가 인식하지 못하는 java 소스코드
CPU는 java 소스코드 (.java)를 인식하지 못하므로 기계어로 컴파일 해주어야 함
java의 소스코드인 .java 파일을 javac(jdk를 설치하면 bin에 존재하는 javac.exe)를 통해 java byte 코드인 .class 파일로 변환 가능 즉, javac의 명령어를 통해 컴파일 가능 (javac -classpath -d)
CPU가 이해하는 코드 -> binary code(이진코드로 된 기계어)
VM이 이해하는 코드 = byte code (.class file)
자바의 메모리 구조
Garbage Collector, Execution Engine, Class Loader, Runtime Data Area

JVM이 작동하다가 class file을 참조하는 순간 동적으로 읽어 메로리에 load되어 JVM에 링크된다.이 때 class Loader가 클래스들을 동적으로 메로리에 로딩하는 역할을 담당.

java Byte code(.class)를 읽고 binary data를 만들어 메소드 영역에 저장하는 동작을 수행. 이 과정에서 java version 을 확인.
Linking
읽어들인 클래스 데이터는 3단계의 linking 과정을 거침.
verify
읽은 class file의 형식이 적합한지 확인
-클래스 파일의 유효성을 검사하여 올바른 형식인지, 부모 클래스나 인터페이스를 올바르게 상속받았는지 등을 확인.
-이 과정은 다소 overHead가 발생하기 때문에 (-Xvertify:none)으로 그냥 진행할 수 있음
prepare
클래스의 static 변수와 기본값에 필요한 메모리 공간 준비
-Prepare 단계는 클래스의 정적 변수(Static variables)를 메모리에 할당하고 기본값으로 초기화하는 과정
Resolution
자바 프로그램이 실행될 때 클래스나 리소스를 찾고 로드하는 프로세스를 의미.
-클래스로딩:클래스가 처음으로 참조될 때 발생하며, 해당 클래스나 리소스를 로딩하여 사용할 수 있도록 준비하는 것을 포함 +(package 분석, 의존성 해결,...)
static 값들을 할당하고, SuperClass의 초기화와, 해당 class의 초기화 진행
Runtime Data Area에 배치된 바이트 코드들을 명렁어 단위로 읽어서 실행
최초 JVM이 나왔을 당시에는 인터프리터 방식이었기때문에 속도가 느리다는 단점이 있었지만 JIT 컴파일러 방식을 통해 이 점을 보완
JIT는 바이트 코드를 어셈블러 같은 네이티브 코드로 바꿈으로써 실행이 빠르지만 역시 변환하는데 비용이 발생 -> 특정 조건 만족시 실행
JIT 컴파일러
자바는 코드를 실행하기 위해서는 바이트코드로 컴파일하는 과정과 바이트코드를 인터프리트하는 과정을 거쳐야 하기 때문에 컴파일 과정만 필요한 다른 프로그래밍 언어보다 느리다. 거기에 더하여 인터프리터는 컴파일러보다 느리기 때문에 성능 문제기 발생할 수밖에 없었다.
JIT 컴파일러는 실행 시점에서는 인터프리터와 같이 기계어 코드를 생성하면서 해당 코드가 컴파일 대상이 되면 컴파일하고 그 코드를 캐싱한다. JIT 컴파일은 코드가 실행되는 과정에 실시간으로 일어나며(그래서 Just-In-Time이다), 전체 코드의 필요한 부분만 변환한다. 기계어로 변환된 코드는 캐시에 저장되기 때문에 재사용 시 컴파일을 다시 할 필요가 없다.
조건
-JIT 컴파일러가 컴파일하는 조건은 얼마나 자주 코드가 실행됐는가
-메서드가 호출된 횟수, 메서드의 루프를 빠져나오기까지 돈 횟수를 기반으로 컴파일되기 위해 큐에서 대기
-오랫동안 돌아가는 루프 문의 경우 JVM은 루프를 위한 코드의 컴파일이 끝나면 루프가 다시 반복될 때는 코드를 컴파일된 코드로 교체하고 더 빠르게 실행된다. 이 교체 과정을 "스택 상의 교체(on-stack replacement, ORS)"라고 부른다.
이 교체 과정을 "스택 상의 교체(on-stack replacement, ORS)"라고 부른다.
Garbage Collector(GC)는 힙 메모리 영역에 생성된 객체들 중에서 참조되지 않은 객체들을 탐색 후 제거하는 역할을 합니다. 이때, GC가 역할을 하는 시간은 언제인지 정확히 알 수 없습니다.
특징
자바에선 가비지 컬렉터가 메모리 관리를 해주기 때문에 한정된 메모리를 효율적으로 사용할 수 있게 하고, 개발자는 메모리 관리, 메모리 누수 문제에 대해서 관리하지 않아도 되어 오롯이 개발에만 집중 할 수 있단 장점이 있다.
단점으론 메모리가 언제 해제되는지 정확하게 알 수 없어 제어하기 힘들고, GC가 동작하는 동안에는 다른 동작을 멈추기 때문에 오버헤드가 발생하는 문제가 있다
JVM의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역입니다. 이 영역은 크게 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack로 나눌 수 있습니다.
Method area
모든 쓰레드가 공유하는 메모리 영역입니다. 메소드 영역은 클래스, 인터페이스, 메소드, 필드, Static 변수 등의 바이트 코드를 보관합니다.
Heap area
모든 쓰레드가 공유하며, new 키워드로 생성된 객체와 배열이 생성되는 영역입니다. 또한, 메소드 영역에 로드된 클래스만 생성이 가능하고 Garbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역입니다.
Stack area

메서드 호출 시마다 각각의 스택 프레임(그 메서드만을 위한 공간)이 생성합니다. 그리고 메서드 안에서 사용되는 값들을 저장하고, 호출된 메서드의 매개변수, 지역변수, 리턴 값 및 연산 시 일어나는 값들을 임시로 저장합니다. 마지막으로, 메서드 수행이 끝나면 프레임별로 삭제합니다.
PC Register
쓰레드가 시작될 때 생성되며, 생성될 때마다 생성되는 공간으로 쓰레드마다 하나씩 존재합니다. 쓰레드가 어떤 부분을 무슨 명령으로 실행해야할 지에 대한 기록을 하는 부분으로 현재 수행중인 JVM 명령의 주소를 갖습니다.
Native method stack
자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역입니다.