자바언어로 작성한 프로그램은 모두 JVM위에서 동작하게 됩니다.
이 JVM이란 무엇이고 어떤 역할을 할까요?
JVM?
JVM은 Java Virtual Machine의 줄임말로, 번역하자면 '자바 가상 머신'으로 해석할 수 있습니다.
JVM에 대해 이해하기 전에 모든 프로그램 언어는 개발자(인간)가 작성한 언어를 컴퓨터(기계)가 이해 가능한 언어로 변경해 주는 과정이 필요하다는 것을 알고 있어야 합니다.
여기서 개발자가 작성한 언어는 코드, 컴퓨터가 이해 가능한 언어는 기계어라고 불립니다.
그리고 코드를 기계어로 변경하는 작업을 컴파일이라고 합니다.
아주아주 간단하게 프로그램이 실행되는 과정에 대해 살펴보자면
'프로그램 작성 -> 컴파일 -> 실행'의 단계로 진행된다고 볼 수 있습니다.
JVM은 위 과정의 '실행' 단계를 위한 것이라고 보시면 됩니다.
Java의 컴파일?
JVM에 대해 알아보기에 앞서 컴파일은 어떻게 할 수 있을까요?
openJDK를 설치했다면 해당 경로에 java, javac파일을 찾을 수 있습니다.
이 javac를 이용해 java파일을 컴파일할 수 있고, 결과물로 class파일이 생성됩니다.
먼저 test.java를 만들어 보겠습니다.
public class Test {
public static void main(String[] args) {
System.out.println("test");
}
}
작성한 Test.java를 실행시키기 위해선 컴파일 과정을 거친 뒤 실행해야 합니다.
그럼 먼저 javac를 이용해 Test.java를 컴파일해 보겠습니다.
$ javac Test.java
$ ll
-rw-rw-r-- 1 chj chj 406 12월 13 17:33 Test.class
-rw-rw-r-- 1 chj chj 99 12월 13 17:28 Test.java
Test.java를 컴파일한 결과로 Test.class 파일이 생성 되었습니다.
컴파일을 통해 생성한 class 파일이 바로 바이트 코드로 변환된 파일입니다.
그럼 이제 이 바이트 코드를 실행시켜 보도록 하겠습니다.
$ java Test
test
java를 이용하여 class의 이름을 넣어주면 간단하게 실행 가능합니다.
정리하자면 자바 프로그램을 실행하는 과정은 아래와 같은 순서대로 진행됩니다.
1. 개발자가 코드를 작성한다 (.java 확장자)
2. java 파일을 바이트 코드로 변환한다. (컴파일, javac 이용)
3. 컴파일 결과로 class 파일이 생성된다.
4. java를 이용하여 class 파일을 실행한다.
다시 JVM
다시 JVM에 대해 정리해 보겠습니다.
자바 언어로 프로 그램을 작성한 뒤 javac를 이용하여 컴파일 과정을 진행하였습니다.
그리고 컴파일 결과물을 이용하여 우리가 작성한 프로그램을 실행해 보았습니다.
이때 java 프로그램의 실행 가능한 환경을 제공해 주는 것이 JVM이라고 할 수 있습니다.
자바 프로그램을 실행하면 컴파일 과정을 거쳐 byte코드를 생성하고 JVM에서 이를 해석하는 과정(interpreter)을 거친 후 실행됩니다.
.java파일 -> 컴파일러 -> .class -> 인터프리터 -> 실행
위 과정을 자세히 이해하기 JVM의 구조를 정리해 보겠습니다.
java 파일을 실행시키는 과정에서 위의 그림처럼 많은 구성 요로를 거치게 됩니다.
JVM은 GC, class loader, execution engine, runtime data area로 구성되어 있습니다.
컴파일 과정을 거친 결과물을 실행시키면 JVM의 구성요소들이 일을 시작하게 됩니다.
JVM의 구성 요소들
GC (Garbage Collector)
자바는 c언어와 다르게 메모리를 자동으로 관리해 주는데 이 역할을 하는 것이 바로 GC입니다.
GC는 사용하지 않는 객체를 찾고 제거하는 역할을 합니다.(Heap영역에서 생긴 garbege를 정리)
garbege는 정리되지 않은 메모리, 유효하지 않은 메모리 주소를 말합니다.
이외에 naver d2블로그에서 GC에 대해 설명한 좋은 글이 있어 링크를 공유드립니다.
stop-the-world, young/old 영역, G1 GC에 대한 내용은 꼭 읽어보세요.
https://d2.naver.com/helloworld/1329
Execution Engine(실행 엔진)
Class Loader에 의해 JVM 메모리 공간(Runtime Data Area)에 적재된 바이트 코드(클래스)를 실행하는 역할을 한다.
내부적으로 바이트 코드를 기계어로 변경하는 작업을 진행하는데 JIT Compiler 방식을 사용한다.
JIT 방식 외의 여러 compile 방식을 비교해 보자.
interpreter : 바이트 코드 읽어가며, 해당 기능에 대응하는 기계어를 실행
정적 compile : 실행 전 모든 프로그램 코드를 기계어로 번역
JIT Compiler : 위 2가지 방법을 혼합한 방법. interpreter 방식으로 진행하다가 여러 번 호출되는 함수나 기타 조건의 기계어를 캐싱해두고 사용한다.(동적 번역 : dynamic translation)
Class Loader
런타임 시에 동적으로 클래스를 로드하고 검사하는 역할을 한다.
Method Area(메서드 영역)
인스턴스 생성에 필요한 정보들을 저장하는 공간이다.(멤버, 생성자, 메서드, 타입, 변수 이름, interface여부 등)
클래스 파일을 읽어 클래스 데이터를 이곳에 저장한다.
Runtime Constant Pool 관리 영역을 가지고 있으며 상수 자료형을 저장한다.
Heap
인스턴스(객체)가 저장되는 공간으로서 모든 인스턴스가 이곳에 생성된다.
GC의 주 대상이다.
Call Stack
메서드의 작업에 필요한 메모리 공간을 제공한다.
메서드 호출 시에 메서드의 작업을 위한 데이터들이 저장된다.(지역변수, 파라미터)
FILO(First In Last Out) 구조를 지닌다.
쓰레드마다 1개씩 존재한다.
PC Register(Program Counter Register)
Program Counter 즉 현재 수행 중인 명령 주소를 가진다.
쓰레드가 생성될 때마다 생성되어 쓰레드를 수행할 수 있게 한다.
Native Method Stack
자바 외 언어로 작성된 네이티브 코드를 위한 영역이다.(C, C++ 등)
참조
- JVM : javacan.tistory.com/entry/1
- naver d2 - GC : d2.naver.com/helloworld/1329
'Java & 스프링 > Java' 카테고리의 다른 글
[Java] extends(상속), implements(인터페이스), abstract(추상) (0) | 2019.04.23 |
---|---|
[Java] 오버로딩, 오버라이딩 (0) | 2019.04.23 |
[Java] 클래스 변수와 인스턴스 변수의 비교 (0) | 2019.04.19 |
[Java] 인스턴스 변수와 클래스 변수 (0) | 2019.04.19 |
자바의 기본형(변수 타입) (0) | 2019.04.18 |
댓글