ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바 메모리 구조
    JAVA 2022. 8. 26. 18:43

     

     

     

    2022.08.24 - [JAVA] - Java Virtual Machine

     

    Java Virtual Machine

    우리는 프로그램을 효율적으로 실행시키기 위해 CS를 공부한다. 멀티 프로세스나 멀티 스레드는 현대 프로그래밍에서 매우 중요한 개념으로, 하드웨어의 성능 향상으로 인한 프로그램 성능 향

    today-studies.tistory.com

     

     

     

    저번 시간에는 JVM에 대해서 알아보았다. 

    이번에는 자바의 메모리 구조에 대해서 알아보자.

     

     

     

     

     

     

     

    이전에 자바가 동작하는 원리는 위 그림과 같다고 했다.

    동작 중에 거쳐가는 영역들이 곧 자바, JVM의 메모리 구조와 같다.

    동작 원리에 대해 복기하는 겸 동작 과정을 따라 각 영역들에 대해 자세히 알아보자.

    ※ Class Loader → Runtime Data Area → 이 외 영역 순으로 설명하고자 한다.

        최대한 쉽게 설명하도록 하겠지만, 세부 설명이 필요한 부분이기에 비유가 거의 없다.

     

     

     

    Class Loader

    자바 컴파일러에 의해 변환된 .class라는 바이트 코드 파일을 가져오는 역할을 한다.

    가져온 바이트 코드 파일을 Runtime Data Area에 저장한다.

     

     

    코드를 실행하다가 ClassNotFoundException 예외를 한 번쯤 본 적이 있을 것이다.

    Class.forName() 메소드를 실행할 때, 인자로 준 클래스 명이 없을 경우 발생한다.

     

    즉, 클래스 로더가 .class 파일을 가져오려 할 때, 맞는 파일 명이 없으면 예외를 발생시킨다는 것이다.

     

     

    클래스 로더가 .class 파일을 찾게 되면 Runtime Data Area에 파일을 저장하게 되는데,

    이때 사용하는 클래스만 저장하고 사용하지 않는 클래스는 나중에 사용할 때 저장하게 된다.

    이를 동적 로딩이라고 하며, 필요한 클래스만 사용하게 되어 메모리 공간을 효율적으로 사용하게 된다.

     

     

     

    Runtime Data Area

    말 그대로, 실행 중에 데이터를 저장하는 영역이다.

    프로세스처럼 스레드가 공유하는 영역과 스레드가 공유하지 않는 영역으로 나뉘는데,

    공유 영역은 Native Method Area, Heap Area가 해당하며

    비공유 영역은 Stack Area, PC Register, Native Method Stack Area가 해당한다.

     

     

     

    Native Method Area

    JVM이 시작될 때 생성되며, 정적(Static) 변수나 클래스 정보들이 담기는 영역이다.

     

    저장 대상 리스트는 다음과 같다.

    • 클래스와 인터페이스

    • 상수(constant)

    • 멤버 변수

    • 메소드

    • 정적(Static) 변수

     

    해당 대상의 접근 제어자, 자료형, 반환 타입 등이 저장되며

    클래스와 메소드의 경우 대상 자체의 정보(이름, 상속 대상 등)도 저장된다.

     

     

     

     

    ※ 밑의 설명은 정확하지 않을 수 있음

    Runtime Constant Pool

     

    클래스 멤버 변수, 메소드, 상수(final) 등의 정보들이 담기는 Native Method Area의 하위 영역이다.

    여기에는 주소 값이 저장되지 않고 Symbol의 형태로 저장된다.

     

     

    즉, 클래스, 메소드의 이름이나 String 값이 저장된다.

     

    Runtime Constant Pool
    "Animal"
    java/lang/String
     

     

     

    이렇게 하면 필요한 데이터를 갖고 있다가 바로바로 꺼내어 쓸 수 있게된다.

    이것을 동적 링킹이라고 하며 위의 동적 로딩과 비슷하다고 보면 될 것이다.

     

     

     

    Heap Area

    new 키워드로 생성한 객체들이 담기는 영역이다.

    Heap 영역은 세 가지 부분으로 구분되며 객체가 얼마나 오래 되었는지에 따라 계속 영역을 이동한다.

    Garbage Collector에 의해 객체가 있는 영역이 옮겨지거나 삭제된다.

     

     

     

    출처) https://yeondube.tistory.com/entry/JVM

     

     

    • Young Generation : 생성되지 얼마 되지 않은 객체들이 저장된다.

    • Old Generation : Young 영역에서 살아남은 객체들이 저장된다.

    • Permanent Generation : 생성된 객체들의 주소값이 저장된다.
                                              Java8 이후 Metaspace로 변경.

     

     

    이에 대해서는 가비지 컬렉터를 알아보면서 자세히 알아보도록 하자.

     

     

     

    Stack Area

    메소드가 호출되면 생성되며 해당 메소드의 정보, 지역 변수, 매개 변수 등 임시 데이터를 저장하는 공간이다.

     

    원시형(int, char 등)은 내부에서 직접 값을 할당받으며,

    참조형(Integer, 클래스 객체 등)은 Heap이나 Method 영역의 주소 값을 가진다.

     

     

     

    PC Register

    바이트 코드에서 현재 실행 중인 명령어의 주소를 저장한다.

    만약 메소드의 5번째 줄이 실행되고 있다면 그곳의 주소를 저장한다.

     

     

     

    Native Method Stack

    자바가 아닌 다른 언어(C, C++)로 제공되는 메소드 정보를 저장하기 위한 영역이다.

    바이트 코드로 변환되어 이 영역에 저장된다.

     

    Stack Area, PC Register, Native Method Stack은 스레드가 생성될 때 1개 씩만 가진다.

     

     

     

     

     

    Execution Engine

    Runtime Data Area에 적재된 바이트 코드를 실행한다.

    Execution Engine을 통해 컴퓨터가 알아들을 수 있도록 바이트 코드가 기계어로 번역된다.

     

     

     

     

    Execution Engine은 Interpreter, JIT Compiler, Garbage Collector를 가진다.

     

     

    Interpreter

    바이트 코드를 실행할 때, 먼저 인터프리터를 이용해 명령어를 실행한다.

    인터프리터란 코드를 한 줄 단위로 실행하는 것으로, 대표적인 인터프리터 언어로 파이썬이 있다.

     

    코드를 한 줄 단위로 실행하기 때문에 반응성은 좋지만 속도가 매우 느리며,

    이것이 자바의 속도 저하의 요인 중 하나로 꼽혔다.

     

     

    JIT(Just-In-Time) Compliler

    이를 보완하기 위해 도입한 것이 JIT(Just-In-Time) 컴파일러이다.

    인터프리터로 코드를 실행하다가 어떤 메소드를 자주 실행한다면,

    그 메소드를 캐싱해두었다가 바뀌는 부분만 컴파일하여 실행한다.

     

     

    Garbage Collector

    필요 없는 객체는 제거하고, 생성된 객체들의 생명 주기를 관리한다.

    가비지 컬렉터에 대해서는 다음 편에 자세히 알아보도록 한다.

     

     

     

     

    JVM의 작동 과정과 함께 간단하게 복기해보면

    Class Loader가 자바 컴파일러에 의해 변환된 .class 바이트 코드를 Runtime Data Area에 적재 

    적재된 바이트 코드는 Execution Engine에 의해 실행

    다양한 클래스, 메소드, 변수들의 정보가 Native Method Area, Heap Area에 저장

    실행 도중 메소드가 호출되면 스레드가 생성되며 Stack Area, PC, Native Method Stack이 생성, 할당

    객체는 GC에 의해 관리되며, JIT 컴파일러가 자주 사용하는 메소드를 컴파일

    위와 같은 과정으로 세부화할 수 있겠다.

     

     

    다음은 Garbage Collector를 알아보기로 하자.

     

     

    참고 자료

    https://yeondube.tistory.com/entry/JVM

    https://sujl95.tistory.com/74

    https://stackoverflow.com/questions/17406159/symbolic-references-in-java

    https://imbf.github.io/interview/2021/03/02/NAVER-Practical-Interview-Preparation-4.html

     

     

     

    'JAVA' 카테고리의 다른 글

    Call by Value / Reference  (0) 2022.09.01
    Garbage Collector  (0) 2022.08.26
    Java Virtual Machine  (0) 2022.08.24

    댓글

Designed by Tistory.