[Java] JVM 구조 및 메모리 영역

🌈 m1naworld ·2022년 11월 8일
0

자바를 잡아! 👻

목록 보기
3/19
post-thumbnail

JVM의 구조는 크게 보면,Class Loader, Execution Engine, Garbage Collector, Runtime Data Area 4가지로 나눌 수 있음.

Class Loader

자바 컴파일러가 컴파일하여 생성된 .class파일들을 엮어서 JVM이 운영체제로부터 할당받은 메모리 영역인 Runtime Data Area로 적재하는 역할을 함.

Execution Engine

클래스 로더에 의해 메모리에 적재된(Runtime Data Area에 배치된) 클래스(바이트 코드)들을 기계어로 변경해 명렁어 단위로 실행하는 역할을 함. 명령어를 하나 하나 실행하는 인터프리터(interpreter)방식이 있고 JIT(Just-In-Time) 컴파일러를 이용하는 방식이 있음.

*최초 JVM이 나왔을 당시 인터프리터 방식이었기 때문에 속도가 느리다는 단점이 있었지만 JIT 컴파일러 방식을 통해 이 점을 보완하였다. JIT는 바이트 코드를 어셈블러 같은 네이티브 코드로 바꿈으로써 실행이 빠르지만 비용이 발생하여, JVM은 모든 코드를 JIT 컴파일러 방식으로 실행하지 않고, 인터프리터 방식을 사용하다가 일정한 기준이 넘어가면 JIT 컴파일러 방식으로 실행된다.

Garbaage Collector

Garbage Collector(GC)는 Heap 메모리 영역에 생성된 객체들 중에서 참조되지 않은 객체들을 탐색 후 제거하는 역할을 함.

🌟 Runtime Data Area

JVM의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역임. 이 영역은 크게 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack로 나눌 수 있음

사진출처

위 그림에서 볼 수 있다시피, PC Register, Stack Area, Native Method Stack영역은 Thread별로 생성되고 Heap, Method Area영역은 모든 Thread가 공유한다.

Method area

JVM이 시작할 때 생성되어 클래스 별로 런타이 상수풀(Runtime Constant Pool), 필드 데이터, 메소드 데이터, 메소드 코드, 생성자 코드 등을 분류해 저장하는 영역

Heap area

new키워드로 생성된 객체와 배열이 생성되는 영역. Method area에 로드된 클래스만 생성이 가능하다. 또한 Garbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역으로 이를 통해 개발자는 객체를 제거하기 위한 별도의 코드를 작성할 필요가 없다.

Stack area

메서드 호출 시마다 각각의 스택 프레임(그 메서드만을 위한 공간)이 생성됨. 그리고 메서드 안에서 사용되는 값들을 저장하고, 호출된 메서드의 매개변수, 지역변수, 리턴 값 및 연산 시 일어나는 값들을 임시로 저장함. 마지막으로, 메서드 수행이 끝나면 프레임 별로 삭제한다.

Last In First Out(LIFO) 구조
스택 영역은 푸시(push)동작으로 데이터를 저장하고, 팝(pop) 동작으로 데이터를 인출함.
이러한 스택은 후입선출방식에 따라 동작하므로, 가장 늦게 저장된 데이터가 가장 먼저 인출된다.
스택 영역은 메모리의 높은 주소에서 낮은 주소 방향으로 할당된다. (반대로 힙 영역은 메모리의 낮은 주소에서 높은 주소 방향으로 할당된다.)

PC Register

Thread가 생성 될 때마다 생성되는 공간으로 Thread가 어떤 부분을 어떤 명령으로 실행할 지에 대한 기록을 나타내는 부분으로 현재 실행되는 부분의 명령과 주소를 저장한다. 이를 이용해서 쓰레드를 돌아가면서 수행할 수 있게 함.

Native method stack

자바 외 언어로 작성된 네이티브 코드를 위한 stack 메모리 영역 (ex. JNI를 통해 호출되는 C/C++)


*stack 영역, heap 영역 예시

  • stack 영역

함수가 호출되어 매개변수로 해당 값이 넘어가면 스코프가 변경되며 n2와 n1, num2와 num1은 결국 다른 데이터가 된다.

함수 호출이 종료되면 해당 지역변수들은 전부 스택에서 사라게 된다.

메인 함수도 종료되면 스택은 전부 비워지게 된다.


  • Heap

지역변수 url += 연산자로 새로운 String을 참조하게 된다. 기존의 https://를 참조하고 있는 변수가 없기에 해당 String은 unreachable object가 되게 된다. 그러면 해당 unreachable object는 GC에 의해 정리된다.



Ref.
기본기를 쌓는 정아마추어 코딩블로그
qkrtkdwns3410.log
찐코딩노예

profile
개발자로 사는 내 삶은 즐거워 👾

0개의 댓글