자바의 슬로건은 “한 번 프로그래밍 한 것은 어떤 플랫폼에서도 실행된다(Write Once, Run Anywhere)”이다.
갑자기 왜 말했냐고? JVM이 그걸 해주기 때문이다 !
JVM은 자바와 운영체제(OS) 사이에서 일종의 중개자 역할을 수행하여 운영체제에 구애받지않고 독립적으로 구동이 가능한 가상 머신이다. 주 역할로는 메모리관리를 수행한다.(GC)
GC?
GC(Garbage Collection)는 자바 애플리케이션에서 사용하지 않는 메모리를 자동으로 수거하는 기능을 말한다.
= Heap영역에 배치된 객체를 관리해준다.
일반적으로 프로그램은 특정 운영 체제에 종속적으로 개발된다. 예를 들어, C++로 작성된 프로그램은 특정 운영 체제나 하드웨어에서 실행되기 위해 컴파일된다. 그러나 자바 프로그램은 먼저 바이트 코드(byte code)로 컴파일된다.
.java파일 → 컴파일 → .class(바이트 코드)
바이트 코드가 .class 파일 형태로 저장된 후, JDK의 자바 컴파일러(javac)를 사용하여 컴파일되면, 이 바이트 코드는 JVM이 이해할 수 있는 기계어로 변환된다. 이러한 변환은 JRE의 일부인 JVM에서 이루어진다.
제일 큰 이유는 OS마다 독립적으로 쓸 수 있다는것이고 쓰기편해진다 라는 거겠다. 굳이 단어로 정리하자면?
1. 플랫폼 독립성
JVM은 플랫폼에 독립적이므로 한 번 작성된 코드를 여러 운영 체제에서 실행할 수 있다.
2. 메모리 관리
JVM은 가비지 컬렉션(GC)을 통해 메모리를 자동으로 관리해준다. = 메모리 누수 방지가 자동
3. 보안
JVM은 바이트 코드를 실행하기 전에 링크과정에서 검증을 수행하여 악의적인 코드의 실행을 방지해준다.
4. 풍부한 생태계
자바 생태계에는 수많은 라이브러리와 프레임워크가 존재한다. 예를 들어, 스프링 프레임워크, Hibernate, Apache Commons 등
1. 속도
VM을 거쳐 코드를 실행하는 것은 일반적으로 직접 하드웨어에서 코드를 실행하는 것보다 느리다. 그러나 최적화 기술이 발전함에 따라 이 차이는 점점 줄어들고 있다.
2. 자원 사용
VM은 자체적인 운영 체제와 런타임 시스템을 유지하기 때문에 추가적인 메모리와 CPU 리소스 자원을 사용하게 된다.
이식성과 플랫폼 독립성이 높다는 장점을 보인다. 또한 GC를 사용하기때문에 메모리관리가 편하다는 점도 있다.
클래스에는 static 값을 설정할 수 있고 이것을 다른 메서드에서 참조해서 사용할 수 있다. 이런 값들을 초기화하는 과정이라고 할 수 있다.
힙과 메소드는 공유 자원이지만, 스택, PC, 네이티브 메소드 스택은 쓰레드에 국한되는 자원이다.
예를들어 에러 메세지 로그를 보면 메소드가 쭉 쌓여있는 것을 볼 수 있다. 스택 안에 쭉 메서드 호출이 쌓여있는 것이다.
JRE는 자바 애플리케이션을 실행하는 데 필요한 모든 라이브러리와 실행 환경을 제공한다. 따라서 바이트 코드가 컴파일된 후, 이를 실행하기 위해서는 JRE가 필요하다. JRE는 JVM과 함께 설치되며, JVM은 JRE의 일부로서 바이트 코드를 실행할 수 있는 환경을 제공한다.
이 과정으로 인해 바이트 코드는 특정 운영 체제나 하드웨어에 종속되지 않고 독립적으로 존재할 수 있다.
다만, JVM은 실행하는 환경(OS)에 맞는 적절한 버전을 선택해서 프로그램을 실행해야만 한다.
스프링 부트 프로젝트를 만들 때 Java말고도 Groovy나 Kotlin을 선택하는 부분을 본적이 있을것이다. 이들은 모두 자바와 높은 호환성을 보이기 때문이다.
JVM은 자바뿐만 아니라 여러 다른 언어들도 지원한다. 예를 들어, 코틀린(Kotlin), 스칼라(Scala), 클로저(Clojure), 그루비(Groovy) 등의 언어는 자바와 높은 호환성을 가지고있으며 JVM 위에서 실행될 수 있다 = JVM을 런타임으로 사용하여 실행될 수 있다.
JVM 계열 언어는 주로 바이트 코드로 컴파일되어 JVM에서 실행된다. 하지만 특정 언어나 프로젝트에 따라 AOT(Ahead-Of-Time) 컴파일러를 사용하여 네이티브 코드(<->Managed Code)로 컴파일할 수도 있다. 이걸로 JVM 없이도 프로그램을 실행할 수 있도록 한다.
AOT?
c/c++
처럼 실행 전에 컴파일하는 방식이다.
자바의 컴파일 방식이 궁금하면?
다만 오해하지말아야하는건 JIT 컴파일러에 비해 성능이 좋다 라는게 아니다. 첫 실행속도가 빠른것이다. 그래서 JIT을 앞서기위해서는 개발이 더 필요하다고 함
JVM이 운영체제의 프로세스라면, Java 프로그램 내의 작업 단위는 스레드다. 스레드들은 JVM 프로세스 내에서 실행되며, 서로 메모리를 공유한다.
즉, 자바 프로그램을 실행하면 JVM 프로세스가 실행되고, JVM 프로세스 안에서 GC 를 포함한 여러 개의 스레드가 실행된다.