ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바(Java) 메모리 구조 / Runtime Data Area
    백엔드/자바 2020. 7. 27. 03:24

    자바의 메모리 구조

    우리가 작성한 소스 코드는 컴파일해 자바 바이트 코드로 바꾸고 이를 JVM으로 실행하게 된다.

     

    그리고 이 과정에서 코드들은 Runtime Data Area 영역에서 실행된다.

     

    즉 OS가 JVM에 할당한 메모리 영역에 맞게 코드들이 분배되고 실행되는 것이라고 생각하면 된다.

    Runtime Data Area

    OS가 JVM에 할당해준 메모리 영역을 Runtime Data Area라고 부른다.

     

    그리고 이러한 메모리 영역은 우선 크게 두 가지로 나뉜다.

     

    쓰레드 별로 생성되는 메모리 영역과 모든 쓰레드가 공유하는 메모리 영역이다.

     

    모든 쓰레드가 공유

    Method Area

    Runtime Constant Pool

     

    Heap Area

    Eden

    Survivor 1

    Survivor 2

    Old

    Permanent

    쓰레드 별로 별도 생성

    Stack Area

     

    PC Resisters

     

    Native Method Stack

     

    모든 쓰레드가 공유하는 메모리 영역

    전체 쓰레드가 공유하는 메모리 영역은 JVM이 시작될 때 실행되고 JVM이 종료되면 해제가 된다.

    1. Method Area (메서드 영역)

    Class Area, Code Area, Static Area 등으로 불리는 해당 영역은 코드에서 사용되는 클래스 파일을 클래스로더로 읽어 클래스별로 런타임 상수풀, 필드 데이터, 메소드 데이터, 메소드 코드, 생성자 코드 등을 분류해서 저장한다.

     

    이때 전역 변수와 정적 멤버 변수(static변수)는 이 영역에 저장되므로 프로그램이 시작부터 종료될 때까지 메모리 남아있게 되고, 이는 전역 변수가 프로그램 종료될 때까지 어디서든 사용이 가능한 이유가 된다.

     

    Method Area에서 저장하는 데이터는 다음과 같다.

     


    Type Information (타입 정보)


     - Type의 전체 이름

     - Type의 직계 하위 클래스 전체 이름

     - Type 클래스 / 인터페이스 여부

     - Type의 modifier (public / abstract / final)

     - 연관된 인터페이스 이름 리스트


    Runtime Constant Pool
    (런타임 상수 풀)


     Type의 모든 상수 정보를 가지고 있다.

     - Type, Field, Method의 모든 Symbolic Reference 정보

     - Constant Pool의 Entry는 인덱스 번호를 통해 접근

     - Object의 접근 등 모든 참조를 위한 핵심 요소


    Field Information
    (필드 정보)


     - Field Type

     - Field modifier(필드 제어자)
     (public / private / protected / static / final / volatile / transient)


    Method Information
    (메서드 정보)


     Constructor를 포함한 모든 메소드
     - Method Name

     - Method Return Type

     - Method Parameter 수와 Type

     - Method modifier
       (public / private / protected / static / final / syncronized  /
        native / abstract)

     - Method 구현 부분이 있을 경우

       ( abstract 또는 native 가 아닐 경우 )

     - Method의 byteCode

     - Method의 Stack Frame의 Operand Stack 및
       Local variable section의 크기

     - Exception Table


    Class Variable
    (클래스 변수)


     Class 변수는 static 키워드로 선언된 변수를 의미

     - 모든 인스턴스에 공유 되며 인스턴스가 없어도
       직접 접근이 가능하다.

     - 변수는 인스턴스의 것이 아니라 클래스에 속하게 된다.

     - 클래스를 사용 하기 이전에 이 변수들은 미리 메모리를 할당 받은
       상태가 된다.

     - final class 변수는 상수로 치환 되어 Runtime Constant Pool에 값을
       복사한다.

     - static 변수는 해당 영역에 저장되지만, 기본형이 아닌
       static 클래스형 변수는 레퍼런스 변수만 저장되고 실제 인스턴스는
       Heap에 저장되어 있다.

    1-1. Runtime Constant Pool (런타임 상수 풀)

    Method Area에 포함되며 클래스 파일 Constant_pool 테이블에 해당하는 영역이다.

     

    - Type, Field, Method로의 모든 레퍼런스를 저장

    - JVM은 Runtime Constant Pool을 통해 실제 메모리상 주소를 찾아 참조한다.

    2. Heap Area(힙 영역)

    JVM이 관리하는 프로그램에서 데이터를 저장하기 위해 런타임시 동적으로 할당하여 사용하는 영역

     

    New연산자로 생성된 객체, 인스턴스와 배열을 저장한다.

     

    힙 영역에 생성된 객체, 배열은 스택 영역의 변수나 다른 객체의 필드에서 참조한다.

     

    참조하는 변수나 필드가 없으면 GC(가비지 콜렉터)의 대상이 된다.

     

    힙 영역은 크게 5가지로 나뉜다.

     

    Heap Area (힙 영역)


    Eden (Young Generation) :

    객체가 생성되면 처음에 저장되는 공간으로

    일정 시간이 되고 Eden의 공간이 꽉 차면

    해당 데이터는 Survivor 1로 복사되는데

    이 때 쓸모없는 데이터는 Minor GC에 의해 삭제된다.


    Survivor 1 & 2 (Young Generation) : 

    Eden에서 살아남은 데이터가 옮겨진다.

    Eden의 공간이 속 꽉차서 데이터가 넘어오고

    공간이 부족해지면 쓸모 없는 데이터는

    Minor GC에 의해 삭제되고 Old로 데이터를 보낸다.


    Old (tenured generation) : 

    Young Generation에서 살아남은 객체가 저장되는 곳이다.

    이곳은 굉장히 오래사용하고 크기가 큰 객체가 대부분이다.

    그리고 이 Old의 공간이 꽉 차게 되면 Minor가 아닌

    Major GC가 실행된다.

    Major GC는 객체들이 살아있는 여부를 파악하기 위해

    모든 쓰레드의 실행을 멈추고 heap을 대대적으로 정리한다.

    이 과정서 Minor에 비해 자원, 시간을 많이 소모한다


    Permanent :

    JDK 8버전부터 삭제되었다.

    현재는 해당 기능을 Metaspace가 대신하고 있다.

    해당 영역은 보통 Class의 meta정보, method의 meta정보,
    static 변수와 상수 정보들이 저장되는 공간이었다.

    그러나 java 8부터는 Meta Spatce영역이 되어 Native 메모리 영역으로
    관리가 넘어갔다.

    다만 Static Object는 Heap 영역으로 옮겨졌다.

    쓰레드 별로 별도로 메모리가 생성되는 영역

    쓰레드가 생성될 때 메모리 영역이 같이 생성되며, 쓰레드 종료되면 해제가 됨.

     

    그래서 method나 heap에 비해 프로그램 내내 사용이 제한적일 수 밖에 없음.

    1. Stack Area(스택 영역)

    자바에서 메서드를 호출할 때 메서드의 Stack Frame이 저장되는 영역.

     

    그리고 그 Stack Frame 안에는 지역변수, 인자값, 리턴값 등이 저장된다.

     

    과정은 이렇다.

     

    (1) 자바는 스레드를 생성하지 않았다면 main 스레드만 존재하고 그에 따라 stack frame도 한개만 있다.

     

    (2) 그 과정에서 메서드를 호출하면 stack프레임을 하나 새로 생성(push)된다.

     

    (3) 그리고 그 안에 메서드와 관계된 지역변수, 매개변수 등을 스택 영역에 저장한다.

     

    (4) 이렇게 스택 영역은 메소드의 호출과 함께 할당되고 메소드의 호출이 완료되면 소멸(pop)한다.

     

    Stack 영역에 저장되는 변수는 다음과 같다.

     


    기본자료형
    (int, double, long, float)


    기본 자료형 변수의 데이터는 stack 영역에 저장된다


    참조 자료형
    (기본 자료형 제외한 나머지)


    참조자료형의 변수 데이터도 stack에 저장된다.

    하지만 이는 실제 데이터가 아닌 참조값

    즉 실제 데이터의 주소값을 가지는 것이다.


    실제 참조 자료형 데이터는 heap의 영역에 존재.


    stack의 영역에선 참조 자료형의

    참조(주소값)만 갖는다.


    소스코드를 만들 때 쓰는 기본 자료형(int, double, long, float) 등의 지역 변수는 Stack의 영역에 저장된다.

     

    메서드 호출이 끝나면 Stack 내 메서드 관련 지역변수도 지워지기 때문에 지역 변수는 전역변수가 저장되는

     

    Method 영역과 달리 메서드 영역 밖에서는 사용할 수 없는 것이다.

    2. PC Resisters(PC 레지스터)

    쓰레드가 하나씩 생성될 때 생기는 것으로 각 스레드마다 존재한다.

     

    PC레지스터는 현재 실행중인 JVM의 명령 주소(Program Counter를 갖고 있는 영역이다.

     

    CPU의 레지스터와는 별개로 Stack 내에서 작동하며, Native Stack을 실행할 땐 사용되지 않는다.

    3. Native Stack(네이티브 스택)

    Java 이외의 언어로 만들어진 코드들을 위한 Stack.

     

    JNI(Java Native Interface)를 통해 호출되는 C / C++ 등의 코드를 수행하기 위한 Stack.

     

    JVM 내부에 영향을 주지 않기 위해 따로 메모리 공간을 활용한다.

Designed by Tistory.