본문 바로가기
Java

JVM (Java Virtual Machine)

by 성건희 2019. 6. 26.
반응형
JVM (Java Virtual Machine)

JVM에 대해서 아시나요?

JVM이란 Java로 개발한 프로그램을 실행하기 위한 가상머신입니다.

운영체제 위에서 동작하므로 플랫폼에 독립적으로 Java 프로그램을 실행시킬 수 있습니다.

 

자바 프로그램 실행과정

jvm

(그림 출처 : https://medium.com/@lazysoul/jvm-%EC%9D%B4%EB%9E%80-c142b01571f2)

  1. 프로그램이 실행되면 JVM은 OS로부터 해당 프로그램이 필요로하는 메모리를 할당받습니다. JVM은 할당 받은 메모리를 용도에 따라 여러 영역으로 나누어 관리합니다.
  2. 자바 컴파일러(javac)가 자바 코드(.java)를 읽어 자바 바이트코드(.class)로 변환시킵니다.
  3. 클래스 로더는 class파일들을 JVM으로 로딩합니다.
  4. 로딩된 class파일들은 실행 엔진(Execution engine)을 통해서 해석됩니다.
  5. 해석된 바이트코드는 Runtime Data Areas에 배치되어 실질적인 수행이 이루어집니다. 이러한 실행과정 속에서 JVM은 필요에 따라서 GC를 수행합니다.

[참고 : https://asfirstalways.tistory.com/158]

 

JVM 주요 시스템

  • Class Loader (클래스 로더)

    • .class 파일을 동적으로 로드, 링크를 통해 배치

 

  • Runtime Data Area (JVM 메모리영역)

    • 프로그램을 수행하기 위해 OS에서 할당받은 메모리 공간

     

  • Execution Engine (실행 엔진)

    • 클래스를 실행시키는 역할

    • 바이트코드(인간 언어)를 Native코드(기계 언어)로 변경

    • 구성

      • Interpreter (인터프리터)

        • 자바 바이트코드를 명령어 단위로 읽어서 실행
        • 한 줄 씩 수행하므로 느리다는 단점이 있음.
      • JIT (Just - In - Time)

        • 인터프리터 단점을 보완한 방식
        • 인터프리터 방식으로 실행하다가 적절한 시점에 바이트코드 전체를 컴파일하여 네이티브 코드로 변경하고, 이후에는 더 이상 인터프리팅 하지 않고 네이티브 코드로 직접 실행하는 방식
        • 네이티브 코드는 캐시에 보관하므로 한 번 컴파일된 코드는 빠르게 실행
        • 컴파일 하는 과정은인터프리터 방식보다 훨 씬 오래걸리므로 한 번만 실행되는 코드라면 인터프리터 방식을 쓰는 것이 유리하다.
      • Gabage Collection

        • GC를 수행하는 모듈 (쓰레드)이 있다.

 

Runtime Data Area

프로그램을 수행하기 위해 OS에서 할당받은 메모리 공간

 

각 Thread 마다 생성 : PC Registers, Native Method Stack, Stack

모든 Thread들이 공유하는 영역 : Heap, Method Area

 

PC Registers

  • 현재 실행 중인 명령의 주소가 저장되는 공간

 

Native Method Stack

  • Native 언어 (C언어)의 메서드가 실행될 경우 저장되는 공간

 

Stack

  • 메서드 관련 작업을 수행하는 공간
  • Stack 자료구조 LIFO 방식

 

Heap

  • 인스턴스(객체)와 배열을 저장하는 공간
  • GC의 대상이 되는 공간 (JVM의 주요 메모리이슈 발생구간)

 

Method Area

  • 적재된 Class에 대한 정보들을 저장하는 공간 (클래스의 놀이터)

  • 클래스 로더가 바이트코드를 메모리에 처음으로 Load하는 공간

  • 다음과 같은 정보가 저장

    • Type Info : Class / Interface의 타입/이름/부모 정보
    • Field Info : 멤버변수의 타입/이름/접근제어자 정보
    • Method Info : 메서드의 이름/리턴타입/매개변수/접근제어자 정보
    • Constant Pool : 상수 정보
    • Class Variable : Static 변수 정보

    => 리플렉션이 가능한 이유

 


GC (Garbage Collection)

  • 알아서 메모리를 정리해주는 녀석

  • GC의 대상 기준 : 객체

    • Heap에서 더 이상 참조되지 않는 객체
    • Stack에서 도달불가능한(Unreachable)객체

 

GC로 인한 성능상 Issue

Mark & Sweep & Compact 알고리즘

  • Mark 단계 : 살아 있는 객체를 식별하여 표시해 놓는 단계
  • Sweep 단계 : Heap의 앞 부분부터 확인하여 살아 있는 것만 남긴다.
  • Compact 단계 : 각 객체들이 연속되게 쌓이도록 힙의 가장 앞 부분부터 채워서 객체가 존재하는 부분과 객체가 없는 부분으로 나눈다.

 

GC 실행 = 애플리케이션 일시정지

  • GC 실행하는 쓰레드만 작동. 나머지는 모두 정지

 

stop-the-world를 막을 순 없다. 최소화하는 것이 중요 (GC튜닝의 중요성)

(stop-the-world : GC를 실행하기 위해 JVM이 애플리케이션 실행을 멈추는 것)

대개 GC 튜닝이란, 이 stop-the-world 시간을 줄이는 것이다.

 

명시적으로 System.gc() 호출

  • 시스템의 성능에 매우 큰 영향을 끼치므로 절대 사용하면 안된다.

gc

 

세대별 GC기법의 적용

eden

(그림 출처 : https://stophyun.tistory.com/37)

캡처

(그림 출처 : 코드스쿼드 FINN - 제이브이엠)

 

알고계신 GC 방식에 대해서 설명해주세요.

Serial GC : 단순하고 전통적인 방식. (Mark & Sweep & Compact) 싱글쓰레드로 성능이 떨어지며 서버용으로 불가

Parallel GC : Serial GC랑 동일하나, Minor GC를 멀티쓰레드로 처리

Parallel Old GC : Parallel GC와 동일하나, Old 영역을 Mark-Summary-Compact로 처리

CMS GC (Concurrent Mark & Sweep GC) : 복잡하나 Low Latency(빠른 응답속도)를 가짐. 메모리와 CPU를 많이 사용하며, Compacting이 기본제공이 아니라 메모리 단편화 심화. 모든 애플리케이션의 응답 속도가 매우 중요할 때 사용

G1 GC (Garbage First) : 가장 빠르다. 일반적인 GC와 다르게 바둑판 영역에 객체할당 및 GC

[참고 : https://d2.naver.com/helloworld/1329]

 

참고

코드스쿼드 FINN - 제이브이엠 발표자료

반응형

댓글