[053] Java는 컴파일 언어인가? 인터프리터 언어인가?

아투·2025년 2월 17일

Java

목록 보기
16/16
post-thumbnail

1. 자바는 하이브리드 언어이다.

결론부터 말하자면 자바는 컴파일 언어, 인터프리터 언어의 특징을 모두 가진 하이브리드 언어이다.

이 구조에 대해 공부하기 앞서서 컴파일과 인터프리터 언어가 무엇인지 간단하게 짚고 넘어 가보고자 한다.


1.1 컴파일 언어

  • 소스 코드를 컴파일러라는 도구를 이용해 기계어(바이너리 코드)로 번역한 후 실행하는 프로그래밍 언어

  • 소스 코드 작성 -> 컴파일 단계 -> 실행 파일 생성 -> 실행

  • 컴파일 언어는 전체 코드를 미리 번역하여 빠른 실행과 오류 검출을 파악할 수 있는 환경을 제공하지만, 플랫폼 의존성과 긴 컴파일 시간이 단점이 될 수 있다.


1.2 인터프리터 언어

  • 소스 코드를 컴퓨터가 한줄 한줄 번역하고 실행하는 프로그래밍 언어

  • 소스 코드 작성 -> 인터프리터에 의한 해석 및 실행 -> 결과 출력

  • 인터프리터 언어 실행시 즉석에서 번역되어 개발 및 디버깅에 용이하고 플랫폼 독립적인 장점을 지녔지만, 실행속도가 느리고 오류 검출이 늦어 질 수 있다.


2. 왜 자바만 이 두가지 특성을 가지고 있을까?

자바가 이러한 하이브리드 언어의 만들고자 했던 배경을 지식을 알아 보았다.

2.1 자바 탄생 배경

java는 1991년 제임스 고슬링(James Gosling)과 선 마이크로시스템즈(Sun Microsystems) 개발팀이 만든 Oak 프로젝트에서 시작되었다. 이 프로젝트의 목적은 가전제품(셋톱박스, TV, 휴대용 기기 등)에서도 실행가능한 언어를 만드는 것이 었다.

당시 프로그래밍 언어들은 대부분 OS에 종속적이어서 플랫폼 독립적인 프로그램을 만들기 어려웠다. C, C++ 같은 언어는 각 OS에 맞게 별도로 컴파일해야 했기 때문에, 다양한 기기에서 실행하려면, 각 환경마다 따로 개발해야 하는 불편함이 있었다.

이를 해결하기 위해, 한 번 작성하면 어디서든 실행할 수 있는 (Write Once, Run AnyWhere, WORA) 언어가 필요했다.


2.2 자바가 하이브리드 방식을 채택한 이유

2.2.1 플랫폼 독립성 확보

  • 해결하고자 한 문제
    당시 C / C++ 과 같은 언어는 특정 OS에 맞게 기계어로 변환되었기 때문에 하나의 프로그램을 여러 플랫폼에서 실행하려면 각각 별도로 컴파일을 해야 했다.

    * C , C++이 각각 별도로 컴파일 해야했던 이유?
    C , C++은 OS와 직접 소통하는 native language이다. 
    즉, 작성된 코드가 운영체제와 하드웨어에서 바로 실행되도록 기계어로 변환된다. 
    하지만 문제는 각 운영체제마다 cpu 구조(아키텍처), 
    시스템 API(함수 호출 방식)이 다르기 때문에, 
    한번 컴파일한 실행 파일을 모든 OS에서 사용할 수 없다.
  • java의 해결 방법
    java는 JVM(Java Virtual Machine)을 사용하여 바이트 코드(중간 코드)로 변환한 후, JVM에서 실행하도록 만들었다.

  • 즉, 자바 코드는 한번만 컴파일하면 모든 OS에서 실행 가능할 수 있다.


2.2.2 실행 성능을 고려한 선택

  • 컴파일 방식의 한계
    기존 컴파일 언어는 OS에 맞춰 별도로 컴파일 해야하는 번거로움이 있었다.

    • java의 절충안
      1. 처음에는 컴파일러(javac)를 사용하여 바이트 코드로 변환
      2. 직접 OS와 소통하는 것이 아닌 JVM에서 실행이 되기때문에 플랫폼 독립성을 유지할 수 있게 된다.
  • 인터프리터 방식의 한계
    기존 인터프리터 언어는 실행 속도가 느리다는 단점이 있었다.

    • java의 절충안
      1. JVM이 바이트코드를 실행(인터프리터)하며 JIT(Just-In-Time) 컴파일러를 활용
      2. 결과적으로 성능 최적화

2.2.3 보안성 강화

C, C++ 같은 언어는 직접적으로 OS의 메모리에 직접 접근 가능하다. 따라서 버퍼 오버플로우와 같은 보안 문제가 발생할 수 있다.

* 버퍼 오버플로우
프로그램이 할당된 버퍼의 크기보다 더 많은 데이터를 입력받아 
버퍼의 경계를 넘어서 데이터를 기록하는 상황, 
이로 인해 인접한 메모리 영역이 덮여쓰여 
예상치 못한 동작이나 프로그램 충돌의 위험이 발생할 수 있으며, 
심각한 경우 악의적인 사용자가 이를 이용해서 
임의의 코드를 실행하여 보안 취약점으로 이어질 수 있다.

3. JIT(Just-In-Time)

JIT는 JVM 내부에서 실행되는 컴파일러이다.

프로그램 실행 중간에 필요한 부분만 실시간으로 컴파일해서 기계어로 변환하는 방식이다.

  1. 자바 소스 코드를 바이트 코드로 변환해준다.

    • 자바 코드를 작성하고 컴파일(javac)하면 바이트 코드(.class 파일)가 생성된다.
  2. JVM이 바이트 코드를 인터프리터 방식으로 실행하도록 해준다.

    • 처음에는 바이트코드를 한줄씩 해석하면서, 실행하는데 인터프리터 방식이므로 속도가 상대적으로 느리다.
  3. JIT가 바이트 코드를 네이티브 코드로 변환시켜준다.

    • 자주 실행되는 코드(핫스팟 코드)를 감지하여 네이티브 기계어로 변환
    • 이후 변환된 기계어 코드는 인터프리터하지 않고 바로 실행
    • 실행 속도가 비약적으로 빨리지는 결과를 얻는다.

0개의 댓글