개발하는 삶
[Java] JVM 에 대해 본문
JVM
- 자바 가상머신
- = 자바 소스 코드 -> 자바 바이트 코드 변환 (자바 가상 머신이 이해할 수 있는 자바 소스코드)
- 자바 프로그램의 실행 구조
- 하드웨어 > 운영체제 > JVM > 자바프로그램
- JVM은 운영체제 위에서 동작하는 소프트웨어임
- 자바 프로그램을 운영체제에 상관없이(리눅스, 윈도우 등) 실행시키기 위해 따로 설계됨
- 바이너리 코드 읽기/검증/실행
- 동작원리
- Java Source(.java) -> Java Compiler (javac) -> Java Byte Code(.class)
- -> JVM(Class Loader, Runtime Data Areas, Execution Engine)
- 해석 ▼
- 자바파일 -> 컴파일러 -> 컴파일 된 자바 바이트코드 -> JVM의 클래스 로더
- -> 런타임 데이터 영역에 로드함 -> 로드된 코드들을 하나씩 가져와 실행엔진으로 실행
- 바이너리코드/바이트코드/기계어
- 바이너리 코드 : 컴퓨터가 이해하는 0과 1로 구성된 이진코드. CPU가 이해할 수 있는 언어
- 바이트 코드 : 바이너리 코드와 의미는 같으나, CPU가 아닌 가상머신에서 이해할 수 있는 언어
- 기계어(네이티브 코드) : 0과 1로 이루어진 바이너리 코드 (*모든 이진코드가 기계어는 아님)
JVM - Class Loader
- 자바 바이트 코드(.class) 를 JVM으로 로딩함
- 자바파일 코드 컴파일 -> JVM이 읽을 수 있는 .class 파일 완성
- Loading (로드)
- System/Application class loader
- 자바 프로그램에 지정된 Class path 내의 클래스 파일들을 로드
- Extension class loader
- 기본 JAVA API 를 제외한 확장 클래스들을 로드
- Bootstrap class loader 다음으로 우선순위를 가짐
- Bootstrap class loader
- JVM 시작 시 최초로 실행되는 클래스 로더
- 다른 모든 클래스로더의 부모
- 최소한의 자바클래스(java.lang.Object, Class, ClassLoader)를 로드함 (기본 JAVA API)
- System/Application class loader
- Linking (연결)
- 검증
- 컴파일러로 변환된 바이트코드가 바이너리코드로 잘 변환 했는지 확인 (클래스 파일 유효 검증)
- 그렇지 않은 경우에 VerifyError 을 던짐
- 준비
- JVM에 의한 메모리 할당
- static field 메모리를 할당하고 기본값으로 초기화함
- 실행
- Symbolic reference 가 direct reference 로 대체됨
- = 대상의 이름이 아닌, 실제 객체의 주소로 참조 관계를 구성함
- 검증
- Initialize (초기화)
- 클래스/인터페이스의 초기화 로직이 실행됨
- Linking 단계에서 초기화된 static 변수들을 원래 설정된 값으로 정의해줌
JVM - Runtime Data Areas
- 프로그램 수행을 위해 운영체제에게 할당받는 메모리 영역
- PC Register
- 스레드당 1개씩 존재
- 스레드 실행 시 현재 실행하는 명령을 저장 후 -> 끝나면 다음 실행될 명령의 주소를 가리킴
- JVM stack
- 스레드당 1개씩 존재 (스레드가 시작될때 생성)
- Stack Frame 이라는 구조체를 저장하는 스택
- Native Method Stack
- JAVA 외의 언어로 작성된 네이티브 코드를 위한 스택(C,C++ 등)을 호출하는 스택
- Heap area
- JVM 당 1개만 존재하는 공유자원
- 인스턴스/객체를 저장하는 공간 (Method area와 다르게 정보가 아닌 실제 데이터가 할당되있는 공간)
- Method area
- JVM이 시작될 때 생성 (JVM당 1개만 존재)
- 모든 스레드가 공유하는 영역
- JVM이 읽어들인 인스턴스화 된 클래스의 정보 등을 보관함
JVM - Execution Engine
- 런타임 데이터 영역에 배치된 바이트 코드를 명령어 단위로 읽어 실행시키는 역할
- Interpreter
- 바이트 코드 명령어를 하나씩 읽고 해석 및 실행함
- 전체적인 실행 속도가 느림 (바이트코드를 다시 기계어로 변환해야 하기 때문)
- JIT 컴파일러
- 인터프리터의 단점 보완
- 바이트 코드 전체를 컴파일 -> 기계어로 변경 후 읽음 (속도 절약)
JRE
- 자바 코드를 실행하기 위한 환경
- JVM의 실행환경을 구현했다고 할 수 있음
- 자바 가상머신, 자바 클래스 라이브러리 등을 포함한 자바 프로그램을 실행하는데 필요한 패키지
JDK
- 자바 기반의 소프트웨어 개발 도구
- JRE + 개발 도구(javac, java 등) 을 포함
JUnit 5
- 자바용 테스팅 기반 프레임워크
- 자바8 이상부터 사용 가능
- JUint Jupiter api (테스트 코드 작성), JUnit Jupiter engine (테스트 실행)
- 주요 어노테이션
- @Test : 테스트 메서드임을 선언
- @BeforeEach : 테스트 실행 전에 실행할 테스트에 사용
- @AfterEach : 테스트 실행 후에 실행한 테스트에 사용
- @Order(2) : 테스트 순서 설정 (2니까 순서 중에 2번째)
- @DisPlayName("text") : 테스트 이름 표시
- Assertions 가 모두 static 메서드가 가능
- assertEquals(a,b) : a와 b가 같은지 비교
- assertThat(a, is(b)) : a와 b가 같은지 비교
'Java' 카테고리의 다른 글
[Java] Stack, Queue, Collection (0) | 2022.07.12 |
---|---|
[Java] Stream (0) | 2022.06.27 |
[Java] 람다식 (0) | 2022.06.26 |
[Java] 제네릭스 (0) | 2022.06.25 |
[Java] 예외, 래퍼 클래스 (0) | 2022.06.25 |