JVM Stack 스택 영역에는 쓰레드 마다 런타임 스택을 만들고, 그 안에 메소드 호출을 스택 프레임(메소드 콜)이라 부르는 블럭으로 쌓는다. 쓰레드 종료하면 런타임 스택도 사라진다. (에러 발생 시에 만날 수 있는 호출 메소드들이 쌓인 ... 모습 ... 콜 스택..)
Stack Frame을 저장하는 스택. JVM은 오직Stack Frame을 push하고 pop하는 작업만 함. 예외 발생 시printStackTrace()등의 메서드로 보여주는 Stack Trace의 각 라인은 하나의 스택 프레임을 표현
Stack Frame(스택프레임) : 메서드가 수행될 때마다 하나의 스택 프레임이 생성되어 해당 스레드의 JVM 스택에 추가되고 메서드가 종료되면 스택 프레임이 제거된다. 각 스택 프레임은Local Variable Array,Operand Stack, 현재 실행 중인 메서드가 속한 클래스의Runtime Constant Pool에 대한 레퍼런스를 갖는다. 지역 변수 배열, 피연산자 스택의 크기는 컴파일 시에 결정되기 때문에 스택 프레임의 크기도 메서드에 따라 크기가 고정된다.
Local Variable Array(지역변수 배열) : 0부터 시작하는 인덱스를 가진 배열. 0은 메서드가 속한 클래스 인스턴스의 this 레퍼런스이고, 1부터는 메서드에 전달된 파라미터들이 저장되며, 메서드 파라미터 이후에는 메서드의 지역 변수들이 저장된다.
Operand Stack(피연산자 스택) : 메서드의 실제 작업 공간. 각 메서드는피연산자 스택과지역 변수 배열사이에서 데이터를 교환하고, 다른 메서드 호출 결과를 push하거나 pop한다. 피연산자 스택 공간이 얼마나 필요한지는 컴파일할 때 결정할 수 있으므로, 피연산자 스택의 크기도 컴파일 시에 결정된다. https://d2.naver.com/helloworld/1230
실행 엔진
인터프리터 바이트 코드를 한줄 씩 실행. -> native code 변환 (라인 바이 라인으로...)
JIT 컴파일러 인터프리터 효율을 높이기 위해, 인터프리터가 반복되는 코드를 발견하면 JIT 컴파일러로 반복되는 코드를 모두 네이티브 코드로 바꿔둔다. 그 다음부터 인터프리터는 네이티브 코드로 컴파일된 코드를 바로 사용한다. ( 인터프리터는 해당 코드 영역을 만났을 때, 인터프리팅하는 것이 아니라, 바로 컴파일된 네이티브 코드를 사용.. 실행 속도 향상!! )
GC(Garbage Collector): 더이상 참조되지 않는 객체를 모아서 정리한다.
STW(stop-the-world) pause 시간 최소화 gc..
GC
힙(heap)내의 객체 중에서 garbage를 찾아낸다. 찾아낸 garbage를 처리해서 heap의 메모리를 회수한다.
Young Generation 영역 : 새롭게 생성한 객체의 대부분이 이곳에 위치. 대부분의 객체가 금방 접근 불가능 상태가 되기 때문에 대부분의 객체가 Young 영역에 생성되었다가 사라진다. 이 영역에서 객체가 사라질 때 Minor GC가 발생했다고 말한다.
Old Generation 영역 : Minor GC이후에도 Young 영역에서 사라남은 객체가 여기로 복사 된다. 대부분 Young 영역보다 크게 할당하며, 크기가 큰 만큼 Young 영역보다 GC는 적게 발생한다. 이 영역에서 객체가 사라질 때 Major GC(혹은 Full GC)가 발생한다고 말한다.