[목차] == 개요 == [[Java]]로 개발한 프로그램을 컴파일하여 만들어지는 [[바이트코드]]를 실행시키기 위한 [[가상머신]]. JRE(Java Runtime Environment)에 포함되어 있으며, Java 컴파일러가 프론트엔드를 담당한다면 Java 가상 머신은 코드 최적화와 백엔드를 담당한다. Java와 함께 [[썬 마이크로시스템즈]]에서 개발되었으며 썬이 [[오라클(기업)|오라클]]에 인수된 후 현재는 오라클이 Java 명칭을 비롯하여 모든 권한을 행사하고 있다. Java 소스 코드는 javac 컴파일러를 거쳐 바이트코드로 변환되며, 이 바이트코드는 JRE에 들어있는 java classloader에 의해 JVM으로 적재되고 JVM은 적재된 바이트코드를 [[JIT]] 컴파일 방식으로 실행한다. JVM은 플랫폼 독립적으로, JVM이 실행 가능한 환경이라면 어디서든 Java 프로그램이 실행될 수 있도록 한다. 즉, Java의 모토인 '''Write once, Run anywhere'''는 JVM을 통해 가능한 것이다. 하지만 특정 운영체제의 특수한 기능을 호출하거나 [[하드웨어]]를 제어하는 등의 일은 JVM으로 할 수 없으며, [[JNI]] 같은 Native 코드를 호출하기 위한 인터페이스를 거쳐야 한다. 즉 일종의 [[샌드박스#s-5]] 환경인 셈. Java 가상머신이라고 해서 Java 바이트코드만 인식하는 것은 아니다. 이 바이트코드를 Java가 아닌 다른 언어들[* [[Kotlin]]이나 [[Scala]], [[Groovy]] 같은 언어들]을 가지고도 생성할 수 있기 때문이다. 따라서 지금의 Java 가상머신은 Java만을 위한 것이라고 생각하면 안 된다. 이름이 Java 가상머신이다 보니 Java에 종속된 게 아닌가 생각할 수도 있지만 그렇지도 않다. Java 가상머신은 코틀린 코드를 컴파일해도 읽을 수도 있고 스칼라 코드를 컴파일해도 읽을 수 있다. 단, 기본이 Java를 위해서 만들어졌기 때문에 Java 소스 코드와 컴파일된 바이트코드는 비교적 직관적으로 연결되지만, 코틀린이나 스칼라의 경우 Java와의 호환성을 고려하긴 했어도 상대적으로는 비직관적이며 필연적으로 Java를 공부해야 한다는 단점이 있다. [[.NET#Framework|.NET Framework]]와 함께 [[가상머신]] 언어 시장을 사실상 양분하고 있다. == 종류 == [[오라클(기업)|오라클]]이 소유한 두 종류의 JVM으로 [[썬 마이크로시스템즈]]에서 개발된 [[http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html|HotSpot]]과 BEA 시스템에서 개발된 [[http://www.oracle.com/us/technologies/java/standard-edition/jrockit/overview/index.html|JRockit]], IBM J9을 기반으로 한 [[https://github.com/eclipse/openj9|Eclipse OpenJ9]]이 있다, 클린 룸 구현에는 [[http://www.kaffe.org/|Kafee]]와 [[IBM]]사의 [[http://www.ibm.com/developerworks/java/jdk/aix/service.html|IBM J9]]가 있다. [[Microsoft Windows|윈도우]], [[리눅스]] 등의 환경에서는 대부분 HotSpot이 사용되지만, [[IBM AIX]]를 운영체제로 사용하는 경우 IBM J9가 널리 사용된다. [[구글]]의 [[안드로이드(운영체제)|안드로이드]]는 Java를 사용하여 개발되었지만, 안드로이드에 있는 [[달빅]] 가상 머신은 Java 바이트코드를 전혀 실행하지 못하므로 엄밀하게 말하면 JVM은 아니다. 다만 Java 바이트코드를 한 번 변환해서 달빅용 코드로 만들고 그걸 실행한다. 좀 바보같긴 하지만, JVM을 포함한 Java의 여러 부분에 걸린 특허를 피하기 위해 내놓은 꼼수. 다만 결국 썬을 인수한 오라클이 이 문제로 소송을 걸었다. 안드로이드가 잘 나가는 걸 본 썬은 독립 회사였을 때 재주는 썬이 넘고 돈은 구글이 벌어서 배는 무지 아팠지만 '''공돌이의 정'''으로 참고 있었다고 한다. 구글이나 썬은 공돌이 회사의 대표격이었으니... 반면 오라클은 문화적으로 봤을 때 전통적인 양복 회사에 가까워서 그딴 건 상관 없었던 모양. 결국 속도 문제[* 달빅은 [[JIT]]라고는 해도 상술한 문제로 인해 속도가 느릴 수밖에 없다.]도 해결할 겸 구글은 달빅을 포기하고 [[안드로이드 런타임]]으로 변경했다. [[마이크로소프트]]에서도 JVM을 내놓은 적이 있었다. [[Java Applet]] 실행을 위해 [[Internet Explorer]] 3부터 제공했다. 그러나 1997년 썬에게 고소당했는데, 이는 MS가 Java 1.1 표준을 무시한 채 자신들 입맛대로 뜯어고쳤기 때문이다.[* MS의 이러한 행보에는 의도적인 비호환성을 통해 결국 Java의 발목을 잡게 하려는 꼼수가 있었다는 지적이 많았다. 비슷한 예로 [[JavaScript]]를 마개조한 JScript가 있으며, 이 역시 IE 9에서 ECMA 표준을 따르도록 변경되면서 레거시 지원으로만 남게 되었다.] 결국 2001년 MS가 패소하면서 자사의 제품에서 MS-JVM을 단계적으로 제거하도록 합의하였으며, 2003년 배포된 [[Windows XP]] 서비스 팩 1a부터는 기본으로 내장되지 않는다. 보안 업데이트는 2007년까지 지원되었다. == 구조 == [[파일:JVM-Architecture.gif]] == 성능 == 바이트코드는 실제의 기계에서 직접 실행되는 것이 아니라 JVM의 해석 단계를 거쳐 실행되므로 [[Java]]로 개발된 프로그램은 같은 기능의 네이티브 언어[* [[C(프로그래밍 언어)|C]], [[C++]], [[Rust]], [[Go(프로그래밍 언어)|Go]] 등]보다 실행 속도가 느리다. 과거에는 바이트코드를 순수하게 [[인터프리터|인터프리트]]하여 매우 느렸으나 현재는 [[JIT]] 컴파일의 도입과 하드웨어의 발전으로 성능이 개선되었다. JVM은 추상적인 머신이며, 메모리의 접근을 가상 머신 차원에서 관리하고 있으므로 런타임에 최적화가 가능하다. 매우 극단적이고 특수한 상황을 가정하면 극히 일부 기능에 대해서는 네이티브 언어보다 더 우월한 성능을 보여 주기도 한다. 하지만 JIT 컴파일 시간, 가비지 컬렉션을 위한 시간 등이 필요하므로 근본적인 한계가 있다.[* 이 부분이 매우 중요해서 JVM이나 .NET CLR 등 가상머신 기반에서 벤치마크를 돌릴 때는 '''1~5회 정도 웜업을 한 후에''' 측정한다.] === 가비지 컬렉션 (GC) === JVM은 [[쓰레기 수집|가비지 컬렉션]]을 수행하여 할당되었다가 더 이상 쓰이지 않는 메모리를 자동으로 회수한다. Full GC(전체 가비지 컬렉션)의 경우 프로그램 수행을 일시 정지(Stop-the-World) 시켜놓고 할 수밖에 없는데, 또 이게 Java 프로그램이 규칙적이지도 않고 이유도 없이 뚝뚝 끊긴다는 악명을 떨치는데 공헌했다. 대규모 서비스의 운영 시 Full GC는 성능에 상당히 심각한 영향을 주므로 프로그래머의 GC 튜닝이 필수로 들어간다. 최신 버전(11~12 이후)의 JVM에는 힙의 크기와 상관없이(수백 MB ~ 수십 TB까지) 일시정지 시간이 10ms 이하인 GC 알고리즘들(ZGC, Shenandoah)이 탑재되어 있다. JVM 모니터링 클라이언트 VisualVM[* [[넷빈즈]]를 기반으로 만들어져 있다.]과 그 플러그인 Visual GC를 설치하면 가비지 컬렉팅 상황을 시각적으로 확인할 수 있다. [[https://visualvm.github.io/|#]] VisualVM 디렉토리의 etc 폴더에 가면 visualvm.conf라는 파일이 있는데, 이 파일에 적혀 있는 visualvm_jdkhome 항목의 주석(#)을 제거한 후 [[JDK]] 폴더의 경로를 적으면 자신이 원하는 버전의 JDK로 모니터링이 가능하다. GC의 상세한 동작 과정에 대해서는 [[http://d2.naver.com/helloworld/1329|이 문서]]를 참고할 것. == JVM 기반 언어 == 이름에 [[Java]]가 들어 있지만 JVM은 '''자신이 무슨 언어를 실행하는지 전혀 관심이 없다.''' 형식만 올바로 지켜서 만들어졌다면 Java가 아니라 '''Java 바이트코드를 만드는 다른 언어'''도 얼마든지 실행할 수 있는 것. JVM의 플랫폼 독립성과 준수한 성능, 그리고 Java 코드와의 손쉬운 상호작용 등의 특징으로 인하여 JVM을 기반으로 하는 Java 이외의 언어들도 많이 개발되어 있다. === 기존 언어의 JVM 구현 === * [[Python]] : [[http://www.jython.org/|Jython]] * [[Ruby]] : [[http://jruby.org/|JRuby]] === JVM 기반의 언어 === * [[Clojure]] * [[Groovy]] * [[Kotlin]] * [[Scala]] === 관련 문서 === * [[프로그래밍 언어]] == 관련 문서 == * [[Java]] * [[가상머신]] [[분류:소프트웨어]]