[Java] Chapter 1-2. 자바의 구동방식(JVM)

 

 

✍️ 자바의 구동방식

자바 소스 코드(.java 파일)를 자바 컴파일러(javac)로 컴파일하면 결과물로 .class 확장자를 가진 파일이 생성된다.

.class 파일은 바로 실행할 수 없는 JVM만이 이해할 수 있는 bytecode로 구성된 파일로 자바 소스 코드를 실행하기 위해선 JVM을 반드시 거쳐서 실행해야 한다.

 

JVM을 사용하는 이유

자바 소스 코드를 실행하는 과정은 어느 정도 알겠는데 굳이 JVM을 사용하는 이유는 뭘까?

이를 이해하기 위해선 Java 이전의 프로그래밍언어인 C를 살펴볼 필요가 있다. 

C/C++ 등 자바 이전의 프로그래밍 언어로 작성된 프로그램은 컴파일 시 재배치 가능한 오브젝트 파일이 생성되는데 이는 컴퓨터가 이해할 수 있는 기계어로 구성되어 있다.

문제는 오브젝트 파일을 만들어내는 컴파일러와 어셈블러는 현재 탑재된 CPU와 OS 구조를 참조해서 오브젝트 파일을 생성하기 때문에 다른 CPU와 OS가 탑재된 시스템에선 해당 오브젝트 파일을 해석할 수 없다. 예를 들어, Intel CPU와 Windows가 탑재된 컴퓨터에서 컴파일된 오브젝트 파일은 Intel CPU와 Linux가 탑재된 컴퓨터에서 해석할 수 없다.

이러한 C 계열 언어의 특징을 '플랫폼에 종속적이다.'라고 한다. 

 

컴파일러와 어셈블러는 탑재된 CPU 구조를 참조한다?

프로그램(실행 가능한 파일)이란 0과 1로 구성된 명령어들의 집합으로 사람에 빗어 표현하면 '공부해, 청소해, 밥 먹어" 등의 컴퓨터가 수행할 동작들을 기계어로 작성해놨다고 생각하면 된다.

앞서 말한 프로그램을 실행하면 명령어들이 메인 메모리상에 적재되고 프로그램은 실행상태에 놓이게 된다. 이렇게 메모리에 적재되어 실행 중인 프로그램을 프로세스라고 부른다. 

이제 CPU는 메인 메모리상에 적재된 명령어를 읽어오고 이에 따른 연산을 수행함으로써 프로그램이 동작하게 되는데 연산을 수행하는 주체인 CPU의 제조사마다 명령어가 다르다는 문제점을 가지고 있다. 마치 '밭 갈아!'라는 명령어를 한국인이라면 잘 이해하지만 외국인은 이해하지 못하는 것처럼 말이다. 

이처럼 컴파일러는 특정 CPU를 타깃으로 한 어셈블리 프로그램을 만들고 어셈블러는 컴파일러의 결과물을 재배치 가능한 오브젝트 파일로 변환한다.  

이러한 이유로 컴파일러와 어셈블러는 CPU 구조를 참조할 수밖에 없는 종속인 형태를 띠게 된다.

 

다시 JVM

다시 자바로 돌아와서 이야기하면, 자바 컴파일러는 탑재된 CPU가 Intel CPU든 AMD CPU든 결과물로 동일한 .class 파일을 생성하면 되고 .class 파일을 현재 환경에 맞게 해석하는 작업은 오롯이 JVM이 수행한다.

정리하면 자바 컴파일러는 OS와 CPU에 구애받지 않고 .class 파일을 만드는 것에 집중하고 그것을 환경에 맞게 해석하는 것은 JVM이 담당한다.

이러한 구조의 장점으로 환경이 변하더라도 코드를 다시 컴파일하거나 수정할 필요 없이 .class 파일과 현재 환경에 맞는 JVM만 있으면 어디서든 실행 가능한 파일을 만들 수 있다. 이러한 자바의 특징을 '플랫폼에 독립적이다.'라고 한다.  

다만 자바도 완벽하게 플랫폼에 독립적이진 않다. C언어의 컴파일러가 CPU에 종속적인 것처럼 자바의 JVM도 CPU와 OS에 종속적일 수밖에 없다. 결국 자바도 현재 실행 환경에 맞는 JVM을 따로 설치해야한다는 불편한 진실이 숨어있다.

 

🍊 커맨드 라인으로 자바 실행하기

1.간단하게 hello world!를 출력하는 코드를 작성하고

public class JavaTest {
	public static void main(String[] args) {
		System.out.println("hello world!");
	}
}

 

2. CMD창을 열어 소스코드가 있는 src 폴더로 이동

C:\Users\USERNAME>

cd C:\Users\USERNAME\Java\workspace\JavaHello\src

C:\Users\USERNAME\Java\workspace\JavaHello\src>

 

3. 자바 컴파일러 javac로 소스코드를 컴파일하기

C:\Users\USERNAME\Java\workspace\JavaHello\src>javac.exe JavaTest.java

 

4. 컴파일의 결과물로 .class 파일이 생생 된다.

 

5. .class 파일을 확장자명 없이 java.exe 명령어에 넘겨주면 자바 소스코드가 실행된다. 

java.exe는 내부적으로 jvm을 구동하는 명령어라고 생각하면 된다.

C:\Users\USERNAME\Java\workspace\JavaHello\src>java.exe JavaTest
hello world!