ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JVM & GC (JAVA)
    Java & Spring/자바 2020. 10. 20. 18:22
    반응형

    JVM과 GC

    • JVM (Java Virtual Machine)
      • 자바 애플리케이션을 클래스 로더를 통해 읽어서 자바 API와 함께 실행하는 것
      • JAVA와 OS 사이에서 중개자 역할 ~> OS에 구애받지 않고 재사용을 가능하게 함
      • 메모리 관리, Garabage collection을 수행
      • 스택 기반의 가상머신
        • cf) ARM 아키텍처와 같은 하드웨어는 레지스터 기반으로 동작
      • 자바 실행 과정
        • JVM은 OS로부터 프로그램이 필요로 하는 메모리를 할당받음
          • JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리
        • 자바 컴파일러(javac)가 소스코드(.java)를 바이트코드(.class)로 변환
        • Class Loader를 통해 class 파일들을 JVM으로 로딩
        • 로딩된 class 파일들은 Execution engine을 통해서 해석
        • 해석된 bite code는 runtime data area에 배치 ~> 수행
        • 실행과정 속에서 필요에 따라 Thread Synchronization과 GC와 같은 관리작업 수행
      • 구성
        • Class Loader(클래스 로더)
          • 클래스파일을 로드하고 링크를 통해 배치하는 작업을 수행하는 모듈
          • runtime시 동적으로 클래스를 로드
          • jar 파일 내 저장된 클래스를 JVM에 탑재 ~> 사용하지 않는 클래스는 메모리에서 삭제
          • 클래스를 처음으로 참조할 때, 해당 클래스를 로드하고 링크하는 역할
        • Execution Engine(실행 엔진)
          • 클래스를 실행하는 역할로 클래스 로더가 JVM내의 런타임 데이터 영역에 바이트코드를 배치하면, 실행 엔진이 실행
          • 바이트코드는 기계어가 아닌 사람이 보기 편한 형태로 기술 ~> 실행 엔진이 바이트코드를 실제 JVM이 해석할 수 있는 기계어로 변경
        • Interpreter
          • 실행 엔진은 바이트 코드를 명령어 단위로 읽어서 실행
          • 한줄씩 실행하는 인터프리터 언어의 단점을 가지고 있음
        • JIT(Just In Time)
          • 인터프리터 방식의 단점을 보완하기 위해 도입된 JIT 컴파일러
          • 인터프리터 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일 ~> 네이티브 코드로 변경 ~> 네이티브 코드로 직접 실행
          • 네이티브 코드는 캐시에 보관 ~> 한 번 컴파일된 코드는 빠르게 수행
          • 컴파일 과정은 인터프리팅보다 오래걸리기 때문에, JVM은 내부적으로 해당 메소드가 얼마나 자주 수행되는지 체크해서 일정 수준을 넘을 때만 컴파일 수행
        • GC(Garbage Collector / Garbage Collection)
          • 아래에 따로 정리
      • Runtime Data Area
        • 프로그램을 수행하기 위해 OS에서 할당받은 메모리 공간
        • runtime data area는 저장 목적에 따라서 5개로 나뉨
        • Method Area( == Class Area == Static Area)
          • 모든 Thread에 공유. 클래스, 변수, Method, static 변수, 상수 정보 등 저장
        • Heap Area
          • 모든 Thread에 공유. new 명령으로 생성된 인스턴스와 객체가 저장
          • 힙 공간은 세개의 영역으로 다시 분할
            • New/Young 영역
              • 객체들이 최초로 생성되는 공간과 이 객체에서 참조되는 객체들이 저장되는 공간
            • Old 영역
              • New area에서 일정 시간 참조하고 살아남은 객체들이 저장되는 공간
              • New area 영역에 객체가 가득차면 GC가 발생
            • Permanent Generation
              • 생성된 객체 정보의 주소값이 저장된 공간
              • Class loader에 의해 로드되는 데이터에 대한 meta 정보가 저장, JVM이 사용
              • Reflection을 동적으로 클래스가 로딩되는 경우에 사용되는데, 내부적으로 Reflection 기능이 자주 사용되는 스프링 프레임워크를 이용할 때, 이 영역에 대한 고려가 필요함
          • 공간이 부족해지면 GC 실행
        • Stack Area
          • 각 스레드마다 하나씩 생성됨
          • Method 내부에서 사용되는 값(지역변수, 매개변수, 리턴값 등)이 저장
        • PC Register
          • 각 스레드마다 하나씩 생성됨
            • 현재 수행중인 JVM 명령 주소값 저장 (CPU의 Register와 비슷한 역할)
        • Native Method Stack
          • 각 스레드마다 하나씩 생성됨
          • OS의 고유 기능(Native)를 Java가 아닌 OS가 구현된 언어(보통 C, C++)로 OS의 고유 기능을 형성
          • 해당 언어의 메소드 호출을 위해 할당되는 구역, 언어에 맞게 stack 형성
          • JNI(Java Native Interface) 표준 규약 제공
    • GC(Garvage Collection / Garvage Collector)
      • GC
      • Young 영역 GC
        • Minor GC
          • 새로 생성된 객체는 Eden 영역에 위치
          • Eden에서 GC가 실행된 이후 살아남은 객체는 Survivor 영역 중 하나로 이동
          • survivor에서 계속 살아있는 객체를 old 영역으로 이동
        • Major GC
          • old 영역에 있는 모든 객체들을 검사 ~> 참조되지 않은 객체를 한꺼번에 삭제
          • 시간이 오래걸리고 실행 중 프로세스가 정지됨, 이를 stop-the-world라고 한다
          • Major GC가 발생 ~> 실행하는 스레드를 제외한 나머지 스레드는 모두 작업을 멈추고, GC 작업을 완료한 이후에 작업 다시 시작
      • Old 영역 GC
        • Serial GC
          • 적은 메모리와 CPU 코어 개수가 적을 때 적합한 방식
          • Old 영역에 살아있는 객체 식별 후, 힙의 앞부분부터 살아있는 것만 남기고, 각 객체들이 연속되게 쌓이도록 힙의 앞부분부터 채워서 객체가 존재하는 부분과 객체가 없는 부분으로 나눈다.
        • Parallel GC
          • Serial GC와 기본적인 알고리즘은 같지만(Mark-Sweep-Compaction), 멀티 쓰레드로 GC를 처리
          • 따라서, Serial GC보다 빠르게 처리 가능
          • 메모리가 충분하고 코어의 개수가 많을 때 적합한 방식
        • Parallel Old GC
          • JDK 5 update 6부터 제공
          • 개선된 알고리즘(Mark-Summary-Compaction) 사용
          • Summary 단계에서 이미 GC가 수행된 영역에서 살아있는 객체를 식별하는 작업을 한다는 것이 Sweep과 차이점
          • Old GC 처리량을 늘려주기 위한 작업
        • Concurrent GC
          • 프로세서가 GC와 처리 역할을 나누어 작업 ~> 일시 정지가 짧아짐
          • 프로세서의 수를 늘릴수록 효과 O, but 한계가 존재
          • 전체 처리량보다 응답 시간이 더 중요한 경우 사용
      • 소멸 대상 선정 방식
        • 알고리즘에 따라 다양하지만, 공통점이 존재
        • 힙 영역 안의 객체 중에서 가비지를 찾고 처리해서 메모리를 회수한다.
        • 참조되고 있지 않은 객체를 가비지라 하고, reachability라는 개념을 활용함
        • 힙 영역에 할당된 객체가 유효한 참조가 있으면 reachability, 없으면 unreachability
        • 참조 사슬 중 최초 참조한 것을 Root Set이라고 칭함
        • 힙 내의 다른 객체에 의한 참조를 제외한 참조가 Root Set이 된다.
          • Java 메서드 실행 시 사용되는 지역변수와 파라미터들에 의한 참조
          • JNI에 의해 생성된 객체에 대한 참조
          • 메서드 영역의 정적 변수에 의한 참조
    반응형

    'Java & Spring > 자바' 카테고리의 다른 글

    String vs (StringBuilder vs StringBuffer) (JAVA)  (0) 2020.10.20
    Final 키워드 (JAVA)  (0) 2020.10.20
    동기화(Synchronized)  (0) 2020.10.20
    Annotation(어노테이션)  (0) 2020.10.20
    객체지향 프로그래밍 (OOP)  (0) 2020.10.20

    댓글

Designed by Tistory.