(상식) 컴퓨터는 어떻게 우리가 작성한 코드를 이해할까?

기본적으로 컴퓨터는 기계어(2진수(0과 1)로 이루어진 코드) 밖에 해석하지 못한다.
바보 녀석 ㅎㅎ
왜 10진수가 아닌 2진수를 사용하게 됐는지 궁금한 사람은 컴퓨터에서 2진수, 8진수, 16진수를 쓰게 된 이유를 참고하자.

따라서 우리는 우리가 짠 코드를 기계어로 바꾸는 행위를 해야한다.

우리의 뇌는 이렇게 좋지도 않고, 효율성 측면에서 이러한 행위를 도와주는 도구가 세 가지가 있다.

1. 컴파일(Compile)

우리가 짠 코드 전체를 기계어로 변환해주는 걸 말한다.
이러한 일을 컴파일러(Compiler)가 대신해준다.
언어에 의존적이므로 C언어 컴파일러, Java 컴파일러 이렇게 따로 따로 존재한다.

우리의 프로그램은 여러 모듈들의 조합으로 이루어져있다.
하지만 컴파일러는 각 모듈들을 컴파일만 해줄 뿐, 합쳐주는 역할을 하진 않는다.
따라서 이 링크는 여러 모듈들을 단일 프로그램으로 합치는 걸 말한다.
링크 하는 프로그램을 링커(Linker)라고 부른다.
링커가 링크한 결과로 단일 실행 파일인 *.exe 등등이 만들어진다.

로드(Load)

단일 실행 파일을 메모리에 적재(Load)시키는 걸 말한다.
로더(Loader)가 이런 일을 한다.

컴파일 언어의 동작 방식

코딩 - 컴파일(컴파일러에 의해) - 링크(링커에 의해) - 로드(로더에 의해)

2. 인터프리트(Interpret)

컴파일 방식은 실행 이전에 컴파일 과정을 거쳐야하므로 시간이 더 소요된다.
또한 내용을 바꿀 때마다 계속 컴파일을 해줘야한다는 단점이 존재한다.
하지만 인터프리트 방식은 소스 코드가 바뀌어도 컴파일 해주지 않아도 된다.
실행하면서 한 줄 한 줄 해석해(인터프리트, Interpret)나가기 때문이다.
이 인터프리트 해주는 녀석을 인터프리터(Interpreter)라고 부른다.
Javascript가 이에 속했다. (모던한 환경이라면 아니라는 소리다.)
하지만 단점으로 한 줄 한 줄 해석하고 실행하기 때문에 컴파일 된 파일을 실행하는 것보다는 느리다는 문제점이 존재한다.

3. JIT 컴파일(Just in Time Compile)

컴파일 방식과 인터프리트 방식의 장점을 짬뽕한 녀석이라고 보면 된다.
컴파일 방식은 기계어로 컴파일 된 코드를 바로 실행하므로 빠른 실행 속도를 보장 받는다.
인터프리트 방식은 소스가 수정돼도 귀찮게 매번 컴파일을 하지 않아도 된다는 장점이 존재한다.
이 JIT 컴파일 방식은 프로그램을 실행하는 시점에서 필요한 부분을 즉석에서 컴파일하는 방식이라 동적 컴파일(Dynamic Compile)이라고도 부른다.
자바의 경우 소스코드(*.java) 파일을 JVM(Java Virtual Machine)이 이해할 수 있는 자바 바이트 코드(*.class)로 변환한다.
하지만 컴퓨터는 자바 바이트 코드를 해석하지 못한다.
따라서 JVM에서는 실행될 때 자바 바이트 코드를 기계어로 해석해주는 JIT 컴파일 방식을 채택했다.
또한 Javascript에서도 JS 엔진(Javascript 코드를 해석해주는 역할을 담당하며 브라우저에 의존적이다.) 중에서는 아래와 같은 녀석들이 JIT 컴파일 방식을 채택했다.

  • 구글에서 개발한 V8(크롬, 오페라와 Node.js)
  • 모질라에서 개발한 TraceMonkey(파이어폭스 3.5+부터 탑재)
  • MS에서 개발한 Chakra(IE9+부터 탑재)
  • Webkit 엔진에 탑재된 JavascriptCore(Safari에 탑재)