일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- jpa n+1 문제
- 최소힙
- 강화학습
- spring
- HTTP
- SpringSecurity
- python
- 엔티티 그래프
- 자료구조
- 알고리즘
- 힙트리
- 완전이진트리
- AVL트리
- 멀티프로세서
- heapq
- Kruskal
- 최대 힙
- 연결리스트 종류
- 연결리스트
- posix
- 백준장학금
- 프로세스
- 스케줄링
- MSA
- 점근적 표기법
- 운영체제
- 이분탐색이란
- 백준 장학금
- JVM
- JPA
- Today
- Total
KKanging
JVM 이란? 본문
JDK, JRE, JVM 의 구분

JVM
JVM은 Java Virtual Machine 의 약자이다. 단순하게는 컴파일러라고 생각할 수 있음 하지만 C/C++ 같은 한번 컴파일로 번역하는 것이 아닌 .class 파일로 컴파일 한 후 JVM 이 한줄한줄 읽는 인터프리터 역할을 하면서 컴파일러가 많이 사용하는 코드는 미리 번역해놓는
인터프리터 + 컴파일러 역할을 한다.
추가로 JVM 은 메모리 관리 ( GC ) 그리고 최근에는 User 레밸 스케줄링의 역할도 관여한다.
JAVA 의 모토는 "Write Once, Run Anywhere"(한 번 작성하면 어디서나 실행 가능) 현대의 언어는 웬만해서는 OS의 종속적이지 않지만 당시 java 의 위 슬로건은 혁명이었다.
java 의 슬로건을 현실화 해준 것이 JVM이다.
JRE
JRE는 자바 실행 환경이다.
JVM, 자바 클래스 라이브러리 , 자바 실행에 필요한 것들이 있다.
JDK
자바 개발 환경으로 자바 애플리케이션을 개발하기 위해 필요한 도구를 제공한다.
보통 자바 몇 버전인지는 JDK 버전을 의미한다.
JDK 는 다음을 포함한다.

- javac : 자바 언어를 자바 바이트 코드로 컴파일 해주는 자바 컴파일러
- javap : 자바 클래스 파일을 역 해석 해주는 역 어셈블리어
- javadoc : 자바 소스 코드에 포함된 주석을 기반으로 API 문서를 자동으로 생성하는 도구
- java : java 언어
- jar : 여러 개의 자바 클래스 파일과 관련된 메타 데이터, 리소스를 하나의 압축 파일로 묶는 형식, 즉 자바 애플리케이션 실행에 필요한 자원이 정해진 형식으로 압축된 하나의 파일
jar TMI
jar는 zip 압축 포멧과 같다.
jar는 2가지 형태로 사용하는데
- java 실행 파일 : 배포와 실행에 더욱 용이하게 됨
- 클래스패스(Classpath): JAR 파일은 클래스패스에 추가되어 다른 자바 프로그램이 해당 JAR 파일 내의 클래스를 사용할 수 있게 된다.
JVM 의 종류?
JVM 은 하나만 있지 않다
- HotSpot JVM
우리가 흔히 JDK 를 설치하여 사용하는 JVM은 현재 OpenJDK의 HotSpot VM 이다.
jdk 8~ jvm은 HotSpot JVM을 사용했다.
HotSpot JVM의 가장 큰 특징인 HotSpot은 C/C++로 개발되어 왔다.
JIT 컴파일러가 특징이다.
- GraalVM
기존 HotSpot JVM 위에서 동작하여 기능을 확장한 Virtual Machine 이다.
이는 JVM에 단점을 보완한 새로운 VM이다.
개선된 JIT , 트러플 , AOT 컴파일러 가 특징이다.
- 다른 vm

HotSpot VM
컴파일 방식

우리가 개발한 java 파일을 jvm 이 인식하는 .class 파일 즉, 자바 바이트 코드로 컴파일 한다.
이는 javac 가 컴파일을 진행한다.
이제 java 바이트 코드를 jvm이 os 가 인식하는 바이너리코드로 컴파일을 진행한다.
- JDK 1.3 이전
초기 JVM은 인터프리터 형식으로 변환하였다.
이는 인터프리터 방식의 단점이 실행 시간이 문제가 되었다.
- JDK 1.3 ~

JVM은 인터프리터와 컴파일러를 동시에 사용한다.
초기에는 인터프리터로 실행을 하지만 profiling이 진행이 되면 profile을 기반으로 최적화된 컴파일을 진행한다. 여기서 컴파일러인 JIT 컴파일러가 사용된다
JIT 컴파일러란?

JIT 컴파일러는 런타임 환경에서 동적으로 컴파일을 하는 컴파일러이다.
그래서 Just In Time의 약자이다.
JIT 컴파일러는 그냥 컴파일만 하는 것이 아닌 최적화를 적용한 후에 컴파일을 진행한다.
HotSpotVm 은
HotSpotVM은 2개의 JIT 컴파일러를 사용한다
C1, C2
차이점은 다음과 같다.
- C1 클라이언트 컴파일러
- 코드 최적화는 덜하지만 빨리 시작됨 속도가 빠름
- 즉시 실행되는 데스크톱 애플리케이션 등에 적합
- C2 서버 컴파일러
- 시작 속도는 느리지만 최적화는 많이 되어 warm-up 후에는 빠름
- 장기 실행되는 서버 애플리케이션 등에 적합
최적화?
여기서 말하는 최적화는 코드 캐시에 컴파일 된 코드를 넣기 때문에 다시 컴파일 또는 인터프리팅을 안해도 된다고 생각할 수 있지만 다른 최적화도 진행된다.
메서드 인라인 , 반복문 최적화 , ….. 등등 많은 최적화를 지원한다.
동작방식은 우선 인터프리터로 코드를 해석한다.
인터프리터가 실행하는 중간에 메서드 호출 횟수 같은 실행 환경 정보를 profiling 한다.
특정 기준이 넘으면 C1으로 넘어가고 최적화 후 컴파일링 된다.
컴파일 되는 실행 환경은 별도 쓰레드에서 진행 되므로 프로그램과 무관하다.
그리고 c1에서도 특정 기준이 넘는다면 C2로 위임 되는 식으로 계층형 컴파일이 진행된다.
HotSpotVM 의 단점?
HotSpotVM 의 JIT 컴파일러는 많은 발전을 해왔다. 하지만 여러 단점이 있다.
- 유지보수
- 일단 JIT 컴파일러는 C/C++ 로 개발 되었다. 이는 초기에는 C/C++에 속도 덕분에 이점을 많이 얻었다. 하지만 시간이 지남에 따라 C/C++ 코드로 된 JIT 컴파일러를 유지보수 및 향상을 할 개발자를 구하기 어려워 졌다.
- 초기 실행시간이 느림하지만 Profiling 하는데 시간이 걸린다(warm up 시간)
- 따라서 JIT 컴파일러의 성능을 보기 위해서는 초기 시간이 필요하다, 이는 요즘 마이크로서비스가 대세인 작은 단위의 서버 실행 관점에서 큰 자바의 단점이 될 수 있다.
- JIT 컴파일러의 최적화 알고리즘은 많은 발전을 했기 때문에 충분한 Profiling이 진행 된다면 일반 컴파일러보다 좋은 성능을 낼 수 있다.
GraalVM
GraalVM 의 등장 배경
HotSpotVM 에 다음에 문제를 해결하려고 한다.
기존 java 애플리케이션은 실행을 위해 JVM을 구동 해야했다. JVM이 구동하면 좋은거 아닌가 생각 할 수 있지만, 요즘 마이크로서비스 같은 인프라가 유행인 상황에서는 좋지 않다.
하나의 작은 기능 실행을 위해 JVM을 실행하고 종료해야하는 비용이 큰 동작을 진행 해야한다.
(아니면 계속 실행하면서 자원을 낭비하게 될것)
추가로 JIT 컴파일러의 유지보수 문제도 해결하고자 했다.
GraalVM 의 구조

C2를 Java 기반의 Graal 컴파일러로 대체 하였다.
이로써 C2의 JIT 컴파일러를 java로 유지보수 할 수 있게 되었고 이는 큰 의미를 가진다.
그리고 기존 JIT 컴파일러보다 더 Advanced 된 JIT 컴파일러이다.
Truffle
트러플 자바는 Truffle 언어 구현 프레임워크로 구축된 JVM 스펙인데, 트러플 자바는 Polyglot API를 제공하는데 이를 통해 런타임 시에 서로 다른 프로그래밍 언어를 결합시킬 수 있다.

AOT 컴파일러

AOT 컴파일러는 기존 JVM 방식과 다르게 정적 컴파일러이다.
AOT는 Java 바이트 코드로 변환이 아닌 JVM에서 실행되는 코드 말고 네이티브 이미지로 변환한다.
네이티브 이미지는 최적화를 어느 정도 적용한 후에 컴파일하기 때문에 높은 성능과 JIT 컴파일러와는 다르게 시작시간에 warm up 시간이 필요 없다는 점이다.
기존에 간단한 함수 형태의 간단한 기능을 가지는 서버리스를 실행할때는 AWS 의 람다를 이용하곤 했다. 기존 JAVA 는 JVM 로딩 그리고 최적화를 위해서는 warm-up 시간 때문에 적합하지 않기 때문
하지만 네이티브 이미지를 사용하면 이런 상황에도 적합하게 사용할 수 있다.
또 동적으로 컴파일 되는 것이 아니기 때문에 메모리가 적게 들어갈 수 있음
네이티브 이미지의 단점
우선 네이티브 이미지 방식이 동적 컴파일보다 무조건 좋은건 아니다.

빠른 시작시간을 지원하긴 하지만 성능이 항상 JIT 보다 AOT 가 좋다는 것이 아니다.
따라서 서버리스 같은 서비스에는 적합하지만 장기간 서비스에서는 오히려 JIT 컴파일러가 더 적합할 수 있다.
그리고 Spring 같은 프레임워크는 동적 실행을 극한으로 사용하기 때문에 이점에서 타협이 필요하다.
'JAVA > JVM' 카테고리의 다른 글
JVM 가비지 컬렉터(GC) 기초 (0) | 2024.08.25 |
---|---|
JVM 클래스 로딩 과정 (0) | 2024.08.13 |
JVM 메모리 구조 (0) | 2024.08.13 |