Java

자바 메모리 구조

옴악핫세 2023. 3. 4. 16:59
  • JVM (Java Virtual Machine)

자바 어플리케이션을 어느 CPU나 OS에서도 실행할 수 있게 지원하는 역할을 수행

자바 코드를 (.java) 컴파일하여 바이트 코드 (.class)로 변환하여 해당 운영체제가 이해할 수 있는 기계어로 실행

  • JVM 구성
    1. Class Loader : JVM으로 바이트 코드를 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈
      로드된 바이트 코드들을 엮어서 JVM의 메모리 영역인 Runtime Data Areas에 배치함
      클래스를 메모리에 올리는 로딩 기능은 한번에 메모리에 올리지 않고, 어플리케이션에서 필요한 경우 동적으로 메모리에 적재하게 됨
      - 클래스 파일 로딩 3단계 : Loading -> Linking -> Initialization
    2. Execution Engine : 런타임 데이터 영역에 할당된 바이트 코드를 실행시키는 주체, 코드를 실행 방식 2가지 존재
      • (1) Interpreter : 바이트 코드를 해석하여 실행하는 역할을 수행, 다만 같은 메소드라도 여러번 호출될 때 매번 새로 수행해야함
      • (2) JIT (Just In time) compiler : 인터프리터 단점 해소, 반복되는 코드를 발견하여 전체 바이트 코드를 컴파일하고 그것을 Native Code로 변경하여 사용
        (Native Code : 자바에서 부모가 되는 C언어 or C++, 어셈블리어를 의미)
    3. Garbage Collector : 더이상 참조되지 않는 메모리 객체 (Garbage)를 모아 제거하는 역할을 수행
      일반적으로 자동으로 실행되지만, 수동으로 실행가능
    4. Runtime Data Area : 어플리케이션이 동작하기 위해 OS에서 할당받은 메모리 공간을 의미
      • Method : static으로 선언된 변수들을 포함하여 Class 레벨의 모든 데이터가 이곳에 저장됨
        JVM 마다 단 하나의 Method Area가 존재하여 GC 관리대상임
        여기에는 Runtime Constant Pool이라는 별도의 영역이 존재 -> 상수 자료형 저장하여 참조
      • Heap : 객체를 저장하기 위한 메모리 영역 -> new 연산자로 생성된 객체, 인스턴스 변수, 배열 저장
        Heap은 2가지 영역으로 구분 가능,
        (1) Young Generation : 생명 주기가 짧은 객체를 GC 대상으로 하는 영역
        (2) Old Generation : 생명주기가 긴 객체를 GC 대상으로 하는 영역
        ! Method area와 Heap area는 여러 스레드들 간에 공유되는 메모리
      • Stack : 각 스레드를 위한 분리된 Runtime stack 영역, 메소드를 호출할 때 마다 생성됨
        스레드의 역할이 종료되면 바로 소멸되는 특성의 데이터를 저장
        각종 형태의 변수나 임시 데이터, 스레드 또는 메소드의 정보를 저장
      • PC(Program Counter) Register: 각 스레드가 시작될 때 생성되며, 현재 실행중인 상태 정보를 저장하는 영역
        스레드가 로직을 처리하면서 지속적으로 갱신됨, 스레드가 생성될 때마다 하나씩 존재함, 어떤 명령을 실행해야 할지에 대한 기록 (현재 수행중인 부분의 주소를 가짐) 
      • Native Method Stack : 실제 실행할 수 있는 기계어로 작성된 프로그램을 실행시키는 영역

Heap 영역을 알아야 메모리 관리를 고려한  코드 작성이 가능함

  • 자바 어플리케이션 실행 과정

1. 어플리케이션이 실행되면 JVM이 OS로부터 메모리를 할당 받음
(JVM은 할당받은 메모리를 용도에 따라 영역을 구분하여 관리)

2. 자바 컴파일러 (javac.exe)가 자바 소스코드 (.java)를 읽어 바이트 코드 (.class)로 변환

3. Class Loader 를 통해 바이트 코드를 JVM으로 로딩

4. 로딩된 바이트 코드는 Execution Engine을 통해 해석됨

5. 해석된 바이트 코드는 Runtime Data Areas에 배치되어 실행됨

(실행되는 과정에서 GC 같은 작업이 수행됨)