보통 프로그래밍 언어를 처음 배우면 C언어로 프로그래밍에 입문한다.
요즘은 파이썬으로 입문하지만...라떼는 C/C++이다
하지만 우리나라는 자바 공화국이고...특히 백엔드 개발을 시작하면 자바는 필수적이라서 자바는 무조건 알아야 한다.
그리고 이때 자바를 배우는 과정에서 자연스럽게 기존에 알았던 C언어와 비교를 하게 된다.
나 또한 이러했고, 따라서 이를 정리해보려고 한다.
전처리 (.c -> .i)
'#include', '#define'과 같이 '#'으로 시작하는 전처리기 구문을 처리한다.
컴파일 (.i -> .s)
소스코드를 어셈블리어로 바꿔준다.
어셈블 (.s -> .o)
어셈블러가 어셈블리어를 오브젝트 코드로 바꿔준다. 이 오브젝트 코드를 기계어라고 한다. 즉, 기계가 드디어 제대로 이해할 수 있다는 소리!
링크 (.o + .a(라이브러리 파일) -> .exe 또는 .out)
링커가 여러가지 오브젝트 파일들과 라이브러리 파일들을 하나로 합쳐 묶어서 실행파일로 생성해준다.
그리고 이 모든 과정을 합해서 빌드라고 한다.
컴파일 (.java -> .class)
자바 소스코드가 바이트코드로 변환된다.
클래스로더
바이트코드를 JVM으로 끌고 들어가는데, 여기에서 링크 과정이 이루어진다.
실행엔진
JVM에 올라온 바이트코드들을 명령어 단위로 하나씩 가져와서 실행한다. 이때 인터프리트와 컴파일 두가지 방식을 병행한다.
인터프리터: 바이트코드를 하나씩 읽어서 실행한다. 이때 하나씩 실행할 때는 빠르지만, 전체적인 속도는 느리다는 단점이 있어서 다음의 컴파일 과정이 도입된다.
JIT 컴파일러: 인터프리터의 단점을 보완하기 위해 도입되었다. 바이트코드 전체를 컴파일해서 바이너리코드로 변경한다. 이때 변경된 바이너리코드가 기계어이다.
C언어는 운영체제에 종속받는 언어이다. 운영체제가 CPU에 맞는 언어로 변환시켜주기 때문이다.
그런데 자바는 JVM이라는 가상머신을 통해 운영체제에 종속받지 않고, 독립적으로 실행할 수 있다.
이 JVM 때문에 이런 차이가 생기지 않았을까 생각한다.
두 언어 모두 컴파일 과정이 있는데, 해당 과정은 공통적으로 개발자가 작성한 소스코드를 전체적으로 다른 코드로 변환해주는 과정이다.
물론 C/C++은 그 결과물이 운영체제에 종속적인 어셈블리 코드고, 자바는 JVM이 이해할 수 있는 언어인 바이트코드이다.
그 이후, C/C++은 먼저 기계어로 바꾼 뒤 링크 과정을 수행하지만, 자바는 먼저 링크 과정을 수행하고 난 뒤 JVM에서 기계어인 바이너리코드로 변경된다.
또한 C/C++은 순수하게 컴파일만 수행되는 언어라면, 자바는 JVM 내에서 컴파일과 인터프리트가 같이 수행되면서 하이브리드 언어가 되었다.