JVM(Java Virtual Machine)에 대해서 알아보자.
JDK
자바 개발 환경으로 자바 어플리케이션을 개발하기 위해 필요한 도구를 제공
자바 언어를 바이트 코드로 컴파일 해주는 자바 컴파일러(javac), 자바 클래스 파일을 해석해주는 역 어셈블리어(javap) 등이 있다.
- 자세한 내용은 Tools and Commands Reference 에서 확인 가능
JRE
- JRE는 자바 실행 환경으로 JVM,자바 클래스 라이브러리, 기타 자바 어플리케이션 실행에 필요한 파일들을 포함
JAVA 동작 과정
- 소스는 .java로 저장된다
- javac 컴파일러가 바이트코드로 바꿔줘서 .class파일로 저장됨
- 작성한 코드를 일시적으로 숨기는 차원
- 바꿔씀으로써 문법 검사 같은 작업을 이후에는 하지않게 됨으로서 시간단축
- but, 이 방법은 소스 코드 변경시 마다 컴파일 다시 필요
- 그래서 이렇게 변경된 바이트 코드(클래스파일)들을 클래스 로더가 jvm메모리 영역(즉, Runtime Data Area)로 로딩
- Runtime Data Area로 로딩된 클래스 파일이 Execution Engine을 통해 실행
- Execution Engine
- 로드된 클래스 파일의 바이트 코드를 실행하는 엔진
- 바이트 코드를 실행시키기 위해서는 바이트 코드를 컴퓨터가 이해할 수 있는 기계어로 바꾸는 작업이 필요
- 인터프리터
- 명령어 한줄한줄 해석하면서 실행
- Just In Time 컴파일러 (jit컴파일러)
- 인터프리터의 단점을 해결하기 위한 방법 → 런타임 시간에 한꺼번에 변경하여 실행
- 인터프리터
- Execution Engine
- 기계어 된 것들이 Runtime Data Area로 배치되어 쓰레드 동기화나 가비지 컬렉션을 수행
- Native Method Interface & Native Method Library
- Native Method Interface
- jvm에 의해 실행되는 코드 중 네이티브로 실행되는 것이 있다면 해당 네이티브 코드를 호출하거나 호출될 수 있도록 만든 일종의 프레임워크
- Native Method Library
- 네이티브 메소드 실행에 필요한 라이브러리
- Native Method Interface
Runtime Data Area (5가지 영역)
메소드와 힙 영역은 모든 쓰레드가 공유하는 공간
Method Area
(모든 쓰레드가 공유하는)클래스, 변수 정보, static으로 선언한 공유 변수 저장됨.
- JVM이 시작될 때 생성되는 공간
- 바이트 코드가 이 영역에 저장됨
Heap
- 동적으로 생성된 개체가 저장되는 영역
- ( ex. new연산 으로 동적으로 생성된 인스턴스 변수가 저장 )
- (이렇게 생성된 변수는 해당 개체가 소멸되기 전이나 가비지 컬랙터가 제거하기 전까진 남아있음)
- 가비지 콜렉션에 대상이 되는 공간
- (효율적인 가비지 컬렉션을 위해 더 세부적으로 5가지 영역으로 나뉨)
나머지 3개는 쓰레드마다 하나씩 생성되는 공간
Stack
임시적으로 사용되는 변수, 메소드의 정보가 저장되는 영역
- → 주로 금방 사용되고 사라지는 데이터가 저장되는 영역
- ex. 지역변수 나 메소드의 매개변수
💡 헷갈리기 좋은 개념 Check!
Reference Type 변수들이 실행마다 스텍에 쌓여 넣었다 뺐다하면 비효율적임
→ stack이 아닌 Heap영역에 진짜 메모리를 저장하고 그 메모리를 참조하는 변수를 stack에 저장
Person p = new Person("이정록", 26);
- 변수 p는 stack에 저장
- 동적으로 생성한 Person 개체 자체는 Heap에 저장
PC Register (프로그램 카운터)
(컴터PC아님)
현재 수행중인 JVM명령어 주소를 저장하는 공간
- 쓰레드가 시작될 때 생성
- 생성될 때마다 생성되는 공간으로 쓰레드마다 하나씩 존재
- 쓰레드가 어떤 부분을 어떤 명령어로 수행할지 저장하는 공간
- 현재 수행중인 JVM 명령의 주소를 갖는다
(운영체제의 프로그램 카운터 CPU레지스터 내부에 있는 다음에 실행될 명령어의 주소를 저장하는 공간을 의미하는 것이 아니다.)
운영체지의 프로그램 카운터(PC, Program Counter) : 프로그램 카운터(PC) 레지스터를 명령어 포인터(IP, Instruction Pointer) 레지스터라고도 부른다. 이 레지스터는 프로세서가 수행할 다음 명령의 주소를 일시적으로 저장하는데 사용된다. 명령을 가져오면 IP(Instruction Pointer)의 값이 증가한다. 따라서 이 레지스터는 항상 가져올 다음 명령의 주소를 가리키거나 현재 명령의 주소를 유지한다
Native Method Stack
자바가 아닌 다른 언어로 작성된 코드를 위한 공간
- (자바 프로그램이 컴파일되어 생성되는 바이트 코드가 아닌) 실제 실행할 수 있는 기계어로 작성된 프로그램을 실행시키는 영역
Class Loader
- Bootstrap Class Loader
- 네이티브 코드로 작성되있다.
- JVM에 내장
- JVM이 시작될 때 실행
- java.lang package 처럼 JVM 실행에 필요한 클래스들을 로딩
- Platform Class Loader
- java.lang.ClassLoader의 인스턴스로 Java SE platform API 등 자바에서 기본적으로 제공해주는 클래스를 로딩할 때 사용된다.
- Bootstrap Class Loader를 부모로 가지고 있다.
- JAVA 8까지는 Extension Class Loader로 불리다가 모듈 시스템이 도입되면서 Platform Class Loader로 명칭이 바뀌었다.
- System Class Loader
- java.lang.ClassLoader의 인스턴스로 유저가 작성한 클래스를 로딩할 때 사용된다.
- ClassPath에 명시된 경로를 통해 클래스를 찾는다.
- Platform Class Loader를 부모로 가지고 있다.
- JAVA 8까지는 Applicaiton Class Loader로 불리다가 모듈 시스템이 도입되면서 Platform Class Loader로 명칭이 바뀌었다.
질문 답하기
JVM이 정확히 무엇이고, 어떤 기능을 하는지 설명해 주세요.
JVM은 자바 가상 머신으로 자바 어플리케이션을 실행하는 가상 머신입니다. 운영체제와 하드웨어 사이에서 중간 역할을 해 Java 바이트 코드를 기계어로 변환해 실행해줍니다. 실제 컴퓨터로 부터 JAVA 어플리케이션 실행을 위한 메모리를 할당 받아 Runtime Data Area를 구성합니다.
- 인터프리터와 JIT 컴파일러를 통해 바이트 코드를 각 운영체제에 맞는 기계어로 해석시켜 실행
- 가비지 콜렉터를 통해 어플리케이션의 동적 메모리를 관리
그럼, 자바 말고 다른 언어는 JVM 위에 올릴 수 없나요?
자바 바이트 코드로 컴파일 될 수 있는 언어라면 JVM에 올릴 수 있습니다. JVM은 클래스 로더가 자바 바이트 코드를 JVM으로 로딩 시키기 때문입니다. Kotlin, Groovy, Scala, Clojure 등이 있습니다.
반대로 JVM 계열 언어를 일반적으로 컴파일해서 사용할 순 없나요?
특정 상황에서 네이티브 코드로 컴파일 될 수도 있다고 합니다.
VM을 사용함으로써 얻을 수 있는 장점과 단점에 대해 설명해 주세요.
격리성과 이식성이 좋다는 장점을 가지고 있습니다.
하나의 VM에 이상이 생겨도 다른 프로그램에 영향을 끼치지 않는다는 격리성과
운영체제와 하드웨어 사이에 중간다리를 해주기 때문에 다른 하드웨어 플랫폼으로 쉽게 이동이 가능하며 특정 운영체제에 종속되지않고 다양한 운영체제 지원이 가능해집니다.
다만 VM을 거쳐 실행해야한다는 점 때문에 속도가 느려질 수 있고 VM 운영을 위한 리소스(CPU, 메모리, 디스크)를 사전에 할당해야 한다는 점이 있습니다.
JVM과 내부에서 실행되고 있는 프로그램은 부모 프로세스 - 자식 프로세스 관계를 갖고 있다고 봐도 무방한가요?
아니요. JVM은 Java 애플리케이션을 실행하는 단일 프로세스입니다. 즉, JVM 자체는 하나의 프로세스이며, JVM 내부에서 실행되는 자바 프로그램은 JVM의 main 스레드가 됩니다. 자바 프로그램은 JVM 프로세스 내에 존재하는 스레드라고 볼 수 있습니다. 따라서 JVM과 내부에서 실행되고 있는 프로그램은 부모-자식 프로세스 관계를 갖고 있다고 하기에는 정확하지 않습니다.
참고
https://www.youtube.com/watch?v=AWXPnMDZ9I0
질문 출처: VSFe
'language > JAVA' 카테고리의 다른 글
[JAVA] 객체지향 프로그래밍이란? (0) | 2024.06.23 |
---|---|
[JAVA] String 활용 (0) | 2024.06.22 |
[JAVA] 배열, 스트림 활용 (0) | 2024.06.22 |
[JAVA] 제네릭(Generic), 제네릭 클래스, 제네릭 메서드, 와일드카드 (0) | 2024.06.22 |
[JAVA][Exception] Map Duplicate key (0) | 2024.06.15 |