[Java] JVM
JVM, JRE, JDK?
자바 프로그램을 개발하기 위해 이런 것들을 설치하는 과정을 거쳤을 것이다.
일단 검색한대로 설치하긴 했는데, 이것들은 전부 무엇이고 어떤 역할을 할까? 한 번 살펴보자.
JVM(Java Virtual Machine)
JVM(Java Virtual Machine)은 자바 가상 머신으로 자바 프로그램 실행 환경을 만들어주는 소프트웨어이다.
JVM은 자바 바이트코드(.class)를 OS에 특화된 코드로 변환(interpreter, JIT compiler)하여 실행시켜준다. 이 때문에 JVM을 사용하면 모든 플랫폼에서 동작하도록 할 수 있다. 즉, 플랫폼에 영향을 받지 않는다는 말이다.
여기서 주의할 점은 Java는 어떠한 JVM에서도 동작시킬 수 있기 때문에 플랫폼에 의존적이지 않지만, JVM 자체는 플랫폼에 의존적이라는 것이다.
즉, 리눅스의 JVM과 윈도우의 JVM은 서로 다르다. 또 Java는 JVM에서만 실행될 수 있으므로 JVM 설치는 필수적이다.
JRE(Java Runtime Environment)
JRE(Java Runtime Environment)는 자바 실행 환경으로 JVM과 각종 라이브러리들이 포함되어 있다.
JRE는 자바 애플리케이션을 실행할 수 있는 최소 단위라고 생각하면된다. JRE가 최소 배포 단위이기 때문에 사용자는 JVM을 따로 받는 것이 아닌 JRE를 통해 자바를 실행시킬 수 있다.
단, 주의할 점은 JRE를 설치했다고 해서 자바 개발을 할 수 있는 것이 아니다.
자바를 개발하고 컴파일하기 위해선 JDK가 필요하다. 때문에 JRE가 있다면 자바 프로그램(.class)을 실행만 시킬 수 있다.
JDK(Java Development Kit)
JDK(Java Development Kit)은 자바 개발 툴로 JRE와 자바 개발에 필요한 툴이 포함되어 있다.
JDK가 설치되어 있어야 자바 컴파일러(javac)를 사용하여 우리가 작성한 자바 코드를 바이트코드(.class)로 컴파일할 수 있다.
Oracle이 Java 11 부터는 JDK만 제공하고 JRE를 따로 제공하지 않는다. 때문에 Java11 부터 JDK가 최소 배포단위가 됐다 생각하면 된다.
JVM 구조
클래스 로더 시스템
자바는 컴파일 타임이 아니라 런타임에 클래스를 로드하고 링크하는 특징이 있다. 이를 동적 로딩(Dynamic Loading)이라고 하는데, 이를 담당하는 부분이 JVM의 클래스 로더이다.
즉, 클래스 로더는 런타임 중에 JVM의 메서드 영역에 동적으로 자바 클래스를 로드하는 역할을 한다.
- 로딩: .class에서 바이트코드를 읽고 메서드 영역에 저장한다.
- 각 자바 바이트코드(.class)는 JVM에 의해 메서드 영역에 다음 정보들을 저장한다.
- FQCN
- 로드된 클래스를 비롯한 그의 부모 클래스 정보
- 클래스 파일과 Class, Interface, Enum의 관련 여부
- 변수나 메서드 등의 정보
- 각 자바 바이트코드(.class)는 JVM에 의해 메서드 영역에 다음 정보들을 저장한다.
- 링크
- 검증(Verify): 읽어들인 클래스가 자바 언어 명세 및 JVM 명세에 명시된 대로 잘 구성되어 있는지 검사한다.
- 준비(Prepare): 클래스가 필요로 하는 메모리를 할당하고, 클래스에서 정의된 필드, 메서드, 인터페이스를 나타내는 데이터 구조를 준비한다.
- 분석(Resolve): 심볼릭 메모리 레퍼런스를 메서드 영역에 있는 실제 레퍼런스로 교체한다. (Optional)
- 초기화: static 값들을 초기화 및 변수에 할당한다.
메모리
메서드 영역
각 클래스 별로 다음과 같은 클래스 수준의 고유 정보를 저장한다.
- Field 정보: 멤버 변수 이름, 타입, 접근제어자 등
- Method 정보: 메서드 이름, 리턴 타입, 매개변수, 접근제어자 등
- Constructor 정보: 생성자
- static 변수: 모든 객체가 공유할 수 있는 정적 클래스 변수
- Runtime Constant Pool: Type의 모든 상수 정보
- Type, Field, Method의 모든 Symbolic Reference 정보
힙 영역
new 키워드로 생성된 객체와 배열이 저장되며, 이는 공유 자원이다.
주기적으로 GC가 제거하는 영역이다.
스택 영역
지역 변수, 파라미터, 리턴 값, 연산에 사용되는 임시 값 등이 생성되는 영역이다.
PC(Program Counter) 레지스터
Thread가 생성될 때마다 생성되는 영역으로 현재 thread가 실행되는 부분의 주소와 명령을 저장하고 있는 영역이다.
네이티브 메서드 스택 (Native Method Stack)
자바 이외의 언어(C, C++ 등)으로 작성된 네이티브 코드를 실행할 때 사용되는 메모리 영역으로 일반적인 C 스택을 사용한다.
실행 엔진
인터프리터
컴파일러에 의해 변환된 바이트코드를 한 줄씩 읽어들이고 실행시키는 역할을 한다.
JIT 컴파일러
인터프리터 효율을 높이기 위해 인터프리터가 반복되는 코드를 발견하면 JIT 컴파일러로 반복되는 코드를 모두 네이티브 코드로 바꿔둔다.
그 다음부터 인터프리터는 네이티브 코드로 컴파일된 코드를 바로 사용한다.
GC(Garbage Collector)
더 이상 참조되지 않는 객체를 모아서 정리한다.
JNI(Java Native Interface)
네이티브 응용 프로그램(하드웨어와 운영체제 플랫폼에 종속된 프로그램들) 그리고 C, C++, 어셈블리 같은 다른 언어로 작성된 라이브러리들을 호출하거나 호출되는 것을 가능하게 한다.
즉, 자바 애플리케이션에서 C, C++, 어셈블리로 작성된 함수를 사용할 수 있는 방법을 제공한다.
jni는 native 키워드를 사용한 메서드를 호출한다.
네이티브 메서드 라이브러리
C, C++로 작성된 라이브러리
위 내용은 다음 강의를 참고하여 작성하였다.
https://www.inflearn.com/course/the-java-code-manipulation/dashboard
'Language > Java' 카테고리의 다른 글
[Java] 동작 파라미터화 코드 전달하기 (0) | 2023.03.28 |
---|---|
[Java] 바이트코드 조작 (0) | 2023.03.22 |
[Java] "" vs new String("") (2) | 2023.03.19 |
[Java] 아무 생각 없이 생성했는데 동일한 객체? (0) | 2023.03.09 |
[Java] abstract class vs interface (0) | 2023.01.20 |
댓글
이 글 공유하기
다른 글
-
[Java] 동작 파라미터화 코드 전달하기
[Java] 동작 파라미터화 코드 전달하기
2023.03.28 -
[Java] 바이트코드 조작
[Java] 바이트코드 조작
2023.03.22 -
[Java] "" vs new String("")
[Java] "" vs new String("")
2023.03.19 -
[Java] 아무 생각 없이 생성했는데 동일한 객체?
[Java] 아무 생각 없이 생성했는데 동일한 객체?
2023.03.09