책너두 (컴퓨터 밑바닥의 비밀) 1일차 : 프로그래밍 언어

요약 (Section 1.1 여러분이 프로그래밍 언어를 발명한다면?)

  • CPU는 단순하지만 빠르다.
    • 프로그래머는 단순하지만 빠른 CPU를 다루기 위해 천공 카드로 컴퓨터 작업을 제어함.
    • 하지만 이는 CPU 관점의 코드일 뿐 인간이 이해하기 어려움
  • 어셈블리어를 통해 인간이 인식할 수 있는 ‘기계 명령어’ 를 이용하여 CPU를 제어하게됨.
    • 하지만 여전히 어셈블리어는 저수준 언어임.
    • 저수준 언어는 매우 추상화되어 있어 구체적으로 ‘우리가 원하는 동작’ 을 하려면 세부 사항들을 하나하나 다 알려줘야 함.
  • 고급 프로그래밍 언어를 통해 CPU를 동작시키기 위한 ‘추상적인 표현’ 을 ‘구체적인 표현’으로 자동 변환할 수 있게 됨.
    • 프로그래밍 언어를 통해 단순한 문장을 표현하기도 하지만, 이들이 중첩되어 복잡한 문장을 표현하기도 함.
      • 이를 재귀라고 함.
      • 재귀가 아무리 복잡하더라도 결과적으로 모두 구문으로 귀결됨.
  • 컴퓨터가 재귀 구조를 이해를 위해 코드를 트리 형태로 표현함.
    • 리프 노드를 번역하면서 결국 전체 트리를 구체적인 기계 명령어로 번역할 수 있게 됨.
  • CPU는 자신만의 고유한 언어가 있음.
    • CPU 마다 같은 언어를 사용하려면 ‘표준 명령어’를 사용해야 함.
    • 이 표준 명령어를 각 CPU가 이해할 수 있는 가상머신(인터프리터)을 통해 CPU가 코드를 이해할 수 있음.

JAVA 가 코드 -> 표준 명령어 -> 인터프리터 -> CPU 명령을 어떻게 내리는가

  1. 자바 코드 작성 (.java)
  2. 자바 컴파일러로 소스파일 컴파일
    1. 자바 바이트 코드 생성됨 (.class)
  3. 컴파일된 바이트 코드는 JVM의 클래스 로더에 전달
    1. 로드 : 클래스파일을 JVM 메모리에 로드
    2. 검증: 자바 언어 및 JVM 명세에 명시된 대로 구성되어 있는지 검사
    3. 준비 : 클래스가 필요로 하는 메모리 할당
    4. 분석 : 클래스 상수 풀 내 모든 symbolic reference 를 direct reference 로 변경함.
    5. 초기화 : 클래스 변수를 초기화
  4. 클래스 로더는 동적 로딩을 통해 필요한 클래스들을 로딩 & 링크함.
    1. 런타임 데이터 영역(JVM 메모리)에 올림.
  5. JVM 실행 엔진이 JVM 메모리에 올라온 바이트 코드를 명령어 단위로 하나씩 가져와서 실행 함.
    1. 인터프리터 방식
      1. 바이트 코드를 하나씩 읽어서 실행함.
      2. 한 줄씩 실행은 빠르나 전체적으로 느림.
    2. JIT 컴파일러 방식
      1. 바이트 코드 전체를 컴파일 하여 바이너리 코드로 변경 후 더이상 인터프리팅 하지 않고 바이너리 코드로 직접 실행하는 방식
      2. 전체적인 실행 속도는 인터프리팅 보다 빠름.

댓글

Designed by JB FACTORY