JVM은 Java Virtual Machine의 준말로 자바 가상 머신을 줄여부르는 용어이다.
우리가 작성하는 자바 소스코드(.java)는 CPU가 인식하지 못하므로 기계어로 컴파일을 해주어야 한다.
자바에서는 자바 컴파일러가 소스코드를 자바 바이트 코드(.class)로 변환하면 JVM이라는 가상 머신에서는 이 바이트코드를 알맞는 기계어로 해석하여
자바를 OS에 종속받지 않고 독립적으로 CPU에서 인식,실행 할 수 있도록 해준다.
즉, JVM은 JAVA와 OS사이의 중개인과 같은 역할을 하는 셈이다.

JVM은 크게 다음과 같이 구성되어 있다.
자바 소스코드(.java)를 컴파일하면 자바 컴파일러가 바이트 코드(.class)로 변환해해준다고 하였다.
이렇게 변환된 class 파일들을 Class Loader가 JVM이 운영체로부터 할당받은 메모리 영역인 Runtime Data Area로 적재해주는 역할을 해준다.
Execution Engine은 Class Loader에 의해 메모리에 탑재된 클래스들을 실행시키는 역할을 한다. 실행은 명령어단위(Operation Code)로 실행되는데 여기에는 2가지 방법이 있다.
- 인터프리터 방식
자바 바이트코드를 명령어 단위로 읽어서 실행한다.
한줄씩 수행하기 때문에 전체수행은 느리지만 명령어 단위의 동작은 빠르다.- JIT(Just In Time Compiler)방식
인터프리터 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일하여 기계어로 변환하고 그 이후에는 더 이상 인터프리팅 하지않고 기계어로 직접 실행한다.
전체적인 동작은 빠르나 컴파일하는데 상당 시간이 소요된다.
Garbage Collector(GC)는 Heap 메모리 영역에 생성된 객체들 중에 참조되지 않은 객체들을 제거하는 역할을 한다.
즉, 더이상 사용되지 않는 인스턴스를 찾아 메모리에서 삭제해준다.
Garbage Collector의 동작시간은 일정하게 정해져 있지 않아 언제 객체를 처리하는지 알 수 없다.
Runtime Data Area는 JVM이 운영체제 위에서 실행되면서 할당받는 메모리 영역이다.
어떤 데이터들이 메모리를 할당받는지에 따라 크게 5가지 영역으로 구분된다.
1. Method Area (Class Area / Static Area)
클래스 정보를 처음 메모리 공간에 올릴 때 초기화되는 대상을 저장하기 위한 메모리 공간
필드 정보(클래스 멤버 변수명, 데이터 타입, 접근 제어자 정보)
메소드 정보(메소드명, 리턴 타입, 접근 제어자 정보)
Type 정보(Interface인지 Class인지)
Constant Pool(상수 풀: 문자 상수, 타입, 필드, 객체 참조 저장)
static 변수
final 클래스 변수
2. Heap Area
객체를 저장하는 가상 메모리 공간이다.
new연산자로 생성된 객체와 배열을 저장한다.
객체들은 모두 Class Area에 할당된 클래스들만 객체로 생성 할 수 있다.
힙영역은 세 부분으로 나눌 수 있다,
Permanent Generation
생성된 객체들의 정보와 주소값이 저장된 공간이다. Class Loader에 의해 load되는 Class, Method 등에 대한 Meta 정보가 저장되는 영역이고 JVM에 의해 사용된다.
객체를 통해 클래스의 정보를 분석해 내는 프로그래밍 기법인 Reflection을 사용하여 동적으로 클래스가 로딩되는 경우에 사용된다.New/Young 영역
Eden: 객체들이 최초로 생성되는 공간
Survivor 0,1: Eden에서 참조되는 객체들이 저장되는 공간Old 영역
New area에서 일정 시간 참조되고 있는,살아남은 객체들이 저장되는 공간
Eden영역이 가득차게 되면 첫번째 Garbage Collector가 발생한다.
Eden영역의 값들을 Survivor 1영역에 복사하고 이 영역을 제외한 나머지 객체는 모두 삭제된다.인스턴스는 소멸 방법과 소멸 시점이 지역 변수와는 다르기에 힙이라는 별도의 영역에 할당된다. 더 이상 인스턴스가 필요가 없어지면,즉 인스턴스의 존재이유가 없을 때 인스턴스는 소멸된다.
3. Stack Area
프로그램 실행과정에서 임시로 할당되었다가 메소드를 빠져나가면 바로 소멸되는 특성의 데이터를 저장하기 위한 공간이다.
지역변수,참조변수,매개변수,리턴 값,연산에 사용되는 임시값 등이 저장된다.
4. PC Register
Thread(프로세스 시작의 단위)가 시작될 때 생성되며 생성될 때마다 생성되는 공간으로 Thread 마다 하나씩 존재한다.
현재 Thread가 실행되는 부분의 주소와 명령을 저장하고 있는 영역이다.
5. Native Method Stack
자바 외의 언어로 작성된 네이티브 코드를 위한 스택이다.
cmd를 실행한 후 Java파일이 있는 디렉토리 경로로 이동한다. 그 후 명령어를 입력해준다.
javac 파일이름.java
컴파일이 완료되면 목적파일인 .class가 생성된다.
컴파일을 하여 생성된 파일인 파일이름.class를 이용하여 실행한다.
java 파일이름
위에 명령어를 입력하면 java코드가 실행된다.
바이트 코드란 가상 머신에서 이해할 수 있는 언어로
CPU가 아닌 가상 머신에서 이해할 수 있는 코드를 위한 이진(0,1) 표현법이다.
자바 소스파일은 자바 컴파일러에 의해 자바 바이트코드로 변환되는데
이렇게 변환된 자바 바이트코드는 JDK가 인식할 수있다.
바이트 코드는 다시 실시간 번역기 또는 저스트 인 타임(just-in-time, JIT) 컴파일러에 의해 바이너리 코드로 변환된다.
JIT(Just In Time) 컴파일러란 프로그램이 실행 중인 런타임에 실제 기계어로 변환해주는 컴파일러다.
동적 번역(Dynamic Translation)이라고도 불리며
초기 JVM은 인터프리터방식으로 바이트코드를 한줄씩 읽어 실행 속도가 느렸지만 이런 단점을 보완하기 위해 JIT 컴파일러가 도입되면서 프로그램의 실행 속도를 향상시킬 수 있었다.
인터프리터 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일하여 기계어로 변환하고 그 이후에는 더 이상 인터프리팅 하지않고 네이티브 코드로 직접 실행하는 방식이다.
JRE란?
JRE는 자바 실행 환경(Java Runtime Environment)의 약자로 자바로 만들어진 프로그램을 실행시키는데 필요한 라이브러리들과 각종 API,그리고 자바 가상 머신(JVM)이 포함되어 있다. 디버거,컴파일러 등과 같이 자바 개발을 위한 도구는 포함하고 있지 않다.
JDK란?
JDK(Java Development Kit)는 자바 애플리케이션을 만드는 데 사용되는 소프트웨어 개발 환경이다.
JDK안에는 개발 시 필요한 라이브러리들과 javac, javadoc 등의 개발 도구들을 포함되어 있고 개발을 하려면 당연히 실행도 시켜줘야 하기 때문에 JRE (Java Runtime Environment)도 함께 포함되어 있다.
JDK와 JRE의 차이점
JDK는 프로그래머가 자바 프로그래밍을 하기 위해 필요한 기능들을 제공해주고 JRE는 자바 프로그램 실행 환경을 구성해준다.
즉, 자바로 프로그램을 직접 개발하려면 JDK가 필요하고 자바로 만들어진 프로그램을 실행시키려면 JRE가 필요하다.
JDK와 JRE의 내부구성
