컴파일러, 인터프리터 둘 다 C 나 자바같은 고레벨언어로 작성된 프로그래밍 언어를 기계어로 변환하는 것은 맞으나 그 과정에 있어서 차이를 보인다.
우선 둘의 차이는
컴파일러는 전체 소스코드를 보고 명령어를 수집하고 재구성 하는 반면
인터프리터는 소스코드의 각 행을 연속적으로 분석하며 실행 한다.
여기까지는 우리가 쉽게 기억하는 둘의 차이지만 좀 더 면밀하게 살펴보고 이해하기 위해 작성하였다.
위 그림과 같이
인터프리터는 고레벨 언어를 바로 기계어로 변환하는 것이 아닌 중간 형태(Intermediate code)로 변환한 다음 실행한다.
컴파일러는 고레벨언어를 바로 기계어(Executable code)로 변환한다.
인터프리터의 특성을 4가지로 정리하자면
어셈블러는 저레벨 언어(어셈블리 언어)의 코드를 기계 수준 언어로 변환하는데 사용되며 만일 8085나 8086같은 마이크로 프로세서라면 어셈블리 언어를 기계어로 변환하는 모듈은 어셈블러 뿐이다. 이를 통해 어셈블리어와 기계어는 다름을 알 수 있다.
컴파일러는 자바 도서를 보면 항상 첫 부분에 나와 있는 helloworld
를 작성하고 javac
명령어를 통해 helloworld 자바 파일을 클래스 파일로 변환하는것을 해볼 수 있다. 이 작업은 자바 컴파일러가 수행한다.
다시말해 자바 컴파일러는 .java 파일을 javac(java compiler)가 바이트코드로 쓰여진 .class 파일로 변환한다.
잠깐? 분명 컴파일러는 기계어로 변환하는 프로그램이라고 하였는데 .class피일안의 바이트코드가 기계어인가??
앞서 컴파일러가 소스코드를 오브젝트코드로, 고레벨언어를 저레벨 언어인 기계어(machine level language)로 변환한다는 것을 알 수 있었다. 그러나 여기서 말하는 기계는 반드시 하드웨어가 아니다.
JVM을 풀어보면 무엇인가? Java Virtual Machine.
즉 JVM을 위해 기계어로 변환한다는 것이다.
사실 JVM의 Machine의 단어가 이렇게 띵을 불러올 줄은 몰랐다. 이런 컴파일러의 특성을 고려하여 굳이 Machine이라는 단어를 넣은 것일까 아니면 내가 Machine은 눈에보이는 기계장치라는 선입견을 가지고 있는 것일까.
다시 돌아와서 그렇다면
자바인터프리터는 자바컴파일러에 의해 변환된 클래스파일내의 바이트코드를 특정 환경의 기계에서 실행될 수 있도록 변환한다. 다른 예를 들어보면 IBM PC에서 작성된 프로그램이 매킨토시에서도 실행할 수 있도록 변환하는다는 의미이다.
정리하자면 다음 그림과 같다.
바로 기계어로 변환하는 컴파일러의 경우는 프로그램이 작성된 기계상에서실행할 때 매우 효율적으로 실행된다. 이는 대부분의 하드웨어 제어 시스템의 프로그래밍언어가 C인 이유이다.
그러나 이와 동시에 기계 종류에 종속된다는 말이기도 하다.
자바 인터프리팅은 자바 컴파일러를 통해 생성된 클래스파일을 기계어로 변환한다.
인터프리팅의 첫 번째 장점은 플랫폼에 종속되지 않는다.
물론 컴파일러를먼저 수행하고 인터프리팅 하는 과정 때문에 컴파일 과정만 필요한 프로그래밍 언어보다는 속도가 느리다.
두 번째 장점은 자바 바이트코드는 컴퓨터와 프로그램 사이에 별도의 버퍼역활을 한다.
이는 보안적으로 장점이 될 수 있다.
인터넷이나 기타 매체를 통해 신뢰할 수 없는 프로그램을 다운받거나 실행할 수 있는 경우 어느정도 보장 될 수 있다. 자바 인터프리터를 사용함으로써 바이러스나 기타 악성 프로그램에 대응 하는 가드 같은 보안 계층에 의해 보호 될 수 있다는 의미이다. 자바와 자바 바이트 코드의 조합으로 플랫폼에 독립적이고 안전한 환경을 제공하면서 동시에 현대 프로그래밍 추상화를 완전히 수용한다.
자바 바이트코드와 자바 인터프리터는 자바 언어에만 해당되는 특성은 아니다.
예를 들어 파이썬 코드를 자바바이트코드로 컴파일한 Jython을 java로 인터프리트 할 때. 또 ML, Lisp, 포트란컴파일러가 자바 바이트코드로 컴파일 하는 것도 비슷한 맥락이다.
또한 유닉스 프로그램인 gcj는 자바소스 파일에서 바로 실행가능한 기계 파일인 a.out로 컴파일할 수 있으며 이는 Sparc 마이크로프로세서에서 네이티브로 실행된다.
추가로 기계어가 자바 바이트코드인 머신을 설계할 수 있다.
Sun에서는 가상 JVM이 아닌 실존 하는 JVM을 정확하게 해냈다. 그렇다면 왜 자바바이트코드 대신 실제 기계어를 사용하지 않는 이유는 무엇일까?
자바 바이트코드는 더 일반적인 고레벨 언어보다 간단하다.
새로운 타입의 컴퓨터에서는자바 컴파일러로를 작성하는 것 보다 자바 바이트코드로 작성하는 것이 더 쉽다. (이 부분은 출처에서 퍼온 내용으로 자세히 알지는 못합니다.)'
즉 자바에서 만큼은 인터프리터 특성 중 한 줄씩 읽는 특성에 집중하기 보다는 플랫폼에 독립적으로 작동할 수 있게 사용됨을 중점을 두고 인터프리터를 이해하는 것이 더 좋을 것 같다.
자바 컴파일러 :
.java
소스파일을 → 바이트코드로 쓰여진.class
클래스 파일로 변환
자바 인터프리터 : 바이트코드로 작성된.class
클래스 파일을 특정 환경의 기계에서 실행될 수 있도록 기계어로 변환