Java로 개발한 프로그램을 컴파일하여 바이트코드를 실행시키기 위한 가상 머신. JRE(Java Runtime Environment)에 포함되어 있으며, Java 컴파일러가 프로트엔드를 담당한다면 Java 가상 머신은 코드 최적화와 백엔드를 담당한다.
Java 소스코드는 javac 컴파일러를 거쳐 바이트코드로 변환되며, 이 바이트코드는 JRE에 들어있는 java classloader에 의해 JVM으로 적재되고 JVM은 적재된 바이트 코드를 JIT 컴파일 방식으로 실행한다.
JVM은 플랫폼 독립적으로, JVM이 실행 가능한 환경이라면 어디서든 Java 프로그램이 실행된 수 있도록 한다.
1. JVM 종류
종류 | 개발사 |
HotSpot | Sun Microsystems |
JRockit | BEA System |
Eclipse OpenJ9 | IMB J9 기반 |
Kafee | 클린 룸 |
IMB J9 | IBM |
- 윈도우, 리눅스 등의 환경에서는 대부분 Hotspot이 사용되지만, IBM AIX에서는 IBM J9이 사용된다.
2. JVM 구조
3. JVM 성능
바이트코드는 실제 기계에서 직접 실행되는 것이 아니라 JVM의 해석 단계를 거쳐 실행되므로 Java로 개발된 프로그램은 같은 기능의 네이티브 언어보다 실행 속도가 느리다. 과거에는 바이트코드를 순수하게 인터프리트 하여 매우 느렸으나 현재는 JIT 컴파일의 도입과 하드웨어의 발전으로 성능이 개선되었다.
JVM은 추상적인 머신이며, 메모리의 접근을 가상 머신 차원에서 관리하고 있으므로 런타임에 최적화가 가능하다. 특수한 상황에서는 네이티브 언어보다 우월한 성능을 보여주기도 하지만, JIT 컴파일 시간, 가비지 컬렉션을 위한 시간 등이 필요하므로 근본적인 한계가 있다.
4. 가비지 컬렉션(GC)
JVM은 가비지 컬렉션을 수행하여 할당되었다가 더 이상 쓰이지 않는 메모리를 자동으로 회수한다. Full GC(전체 가비지 컬렉션)의 경우 프로그램 수행을 일시정지(Stop-the-world) 시켜놓고 할 수밖에 없는데, 이게 규치적이지 않고 이유 없이 뚝뚝 끊긴다는 악명을 떨치는데 공헌했다. 대규모 서비스의 운영시 Full GC는 성능에 상당히 심각한 영향을 주므로 프로그래머의 GC튜닝이 필수로 들어간다. 최신 버전(11~12 이후)의 JVM에는 힙의 크기와 상관없이 일시정지 시간이 10ms이하인 GC 알고리즘들(ZGC, Shenandoah)이 탑재되어 있다.
JVM 모니터링 클라이언트 VisualVM과 그 프러그인 Visual GC를 설치하면 가비지 컬렉팅 상황을 시각적으로 확인할 수 있다.
참조: 나무위키(https://namu.wiki/w/%EC%9E%90%EB%B0%94%20%EA%B0%80%EC%83%81%20%EB%A8%B8%EC%8B%A0?from=JVM)