[Java] JVM과 자바 메모리 영역

szlee·2023년 10월 22일
0

Java

목록 보기
4/23

JVM?

Java Virtual Machine.
자바를 실행하는 머신. 자바를 돌리는 프로그램.
자바로 작성된 모든 프로그램은 JVM에서만 실행될 수 있으므로 자바 프로그램을 실행하기 위해선 반드시 자바 가상 머신이 설치되어 있어야한다.
자바 코드에서 main()메서드를 호출하여 자바 프로그램을 실행하는 역할을 한다.
-> 자바 프로그램을 모든 플랫폼에서 제약 없이 동작하도록 할 수 있다.



JVM이 필요한 이유?

  • 컴퓨터 OS마다 바이트 저장 방식이 다르기 때문에, 특정 OS나 CPU구조에 맞춰진 컴파일러에 의해 다르게 컴파일 된다.
    즉, 다른 OS, CPU구조를 사용하는 환경해서는 해당 기계어를 이해할 수 없다.(ex.C언어)
  • JAVA언어로 작성한 소스파일은 직접 운영체제로 가서 실행하는 것이 아니라, JVM을 거쳐서 운영체제와 상호작용을 한다.
  • JVM만 있으면 운영체제 상관없이 프로그램을 제약 없이 실행할 수 있다.
  • JVM이 컴파일된 코드와 운영체제 사이에서 해당 환경에 알맞게 변환해준다.

Java는 OS에 종속적이지 않다.
OS에 종속되지 않고 실행되기 위해선 OS위에서 Java를 실행시킬 무언가가 필요한데 그게 바로 JVM이다.

단, 단점은 OS가 직접 제어하는 방식에 비해 속도가 느리다.



JVM 구조

Class Loader
클래스 파일을 JVM 메모리에 로드.

Runtime Data Area
프로그램 수행을 위해 OS에서 할당받은 메모리 공간.
PC 레지스터(PC Register), 스택(Stack), 네이티브 메서드 스택(Native Method Stack)은 스레드(Thread)마다 하나씩 생성되고 힙(Heap), 메서드(Method) 영역은 모든 스레드가 공유해서 사용

Execution Engine
바이트 코드로 된 .class파일을 실행한다. 바이트 코드를 한줄씩 읽고 다양한 메모리 영역에 나타난 데이터와 정보를 사용하고 명령을 실행한다.



Java 프로그램 실행 과정

빌드 시,
1. 개발자가 자바 소스 파일 작성 (.java)
2. 자바 컴파일러가 자바로 작성된 소스코드 .java파일을 .class파일인 바이트 코드로 컴파일한다. (JVM이 이해할 수 있는 코드)

런타임 시,
1. 바이트 코드class loader에게 전달.
2. 동적 로딩을 통해 Runtime Data Area에 배치.(JVM의 메모리에 올린다.)
3. Execution EngineJVM 메모리에 올라온 바이트 코드들을 JVM 내부에서 기계가 실행할 수 있는 형태로 변경.

  • Java Interpreter : 바이트코드 명령어를 한줄씩 읽어 기계어로 바꾼다. 그 후 변환된 코드를 실행.<느리다>
  • JIT(Just-In-Time) Compiler : 인터프리터 단점 보완하기 위해 도입된 방식. 바이트코드 전체를 기계어로 바꾼다. <인터프리터보다 빠르다>

기계어?

  • 컴퓨터가 인식할 수 있는 0과 1로 이루어진 바이너리 코드
  • 모든 바이너리 코드가 기계어인것은 아니다.

  • 기계어는 특정한 언어가 아니고 특정 CPU에서 사용하는 명령어 집합이다. CPU에 따라 같은 동작을 하는 명령어지만 완전히 다른 0과 1이 나열될 수 있다.

바이트 코드?

  • 가상머신이 이해할 수 있는 언어. 가상 머신이 이해할 수 있는 0과 1로 구성된 바이너리 코드.
  • 특정 언어로 작성된 소스코드를 가상 머신이 이해할 수 있는 중간 코드로 컴파일한 것.


JVM 메모리 구조

Static 영역

(Method Area, Class Area, Code Area라고도 불린다.)
JVM이 시작될 때 생성되는 공간으로 바이트코드가 이 영역에 저장된다.
클래스 정보, 변수 정보, static으로 선언한 변수가 저장되고 모든 스레드가 공유하는 영역.

Stack 영역

지역변수, 메서드의 매개변수, 임시적으로 사용되는 변수, 메서드의 정보가 저장되는 영역. 해당 메서드의 호출이 종료되면 이 안에 선언된 변수는 사라진다.
메모리 관리가 메서드 호출과 종류에 따라서 자동적으로 스택 프레임이 생겼다 사라지고 하기 때문에 이 스택 메모리 영역을 개발자가 딱히 관리해 줄 필요는 없지만,
메서드가 무언가를 호출하는 작업을 너무 많이 하게 되면(함수1에서 함수2 호출, 함수2는 또 함수3 호출, ...)스택 프레임이 스택 메모리에 너무 많이 쌓여서 더 이상 남아있는 스택 메모리 공간이 없으면 어플리케이션이 죽어버림..

  • 스택 프레임 : 해당 메서드가 실행됨에 따라 스택 영역에 해당 메서드에 해당하는 스택 프레임이 생성됨

Heap 영역

동적으로 생성된 객체가 저장되는 영역. new를 통해 동적으로 생성된 인스턴스 변수가 저장된다. GC의 대상이 되는 공간.

  • 스택 프레임의 해당 메서드의 변수는 heap영역에 있는 객체를 가리키는 주소값을 저장하게 된다.






reference 1
reference 2
reference 3
reference 4
reference 5

profile
🌱

0개의 댓글