본문 바로가기

웹 개발

자바 가상 머신(Java Virtual Machine, JVM)

자바 가상 머신

자바에 대한 설명을 들으면 자바는 어느 OS도 쉽게 돌아간다는 장점이 있다고는 듣는다. 이는 자바가 JVM이라는 특별한 환경에서 돌아가기 때문이다.

가상 머신(Virtual Machine, VM)

자바 가상 머신에 대해 알기위해선 가상 머신에 대한 개념부터 알고 있어야한다. 거상 머신이란 시스템 위에 자체 CPU, 메모리 등의 환경을 갖추고 하나의 컴퓨터처럼 돌아가는 것이다. 하이퍼바이저를 사용하여 가상 머신 환경과 그 외 시스템 환경의 리소스를 구분하여 사용할 수가 있다. 여러개의 VM이 존재할 수가 있다. 가상 서버를 구현할때 시스템의 리소스의 낭비없이 효율적으로 사용할 수 있다는 장점이 있다.

자바 가상 머신

JVM은 자바 프로그램을 돌릴 수 있는 가상 컴퓨터이다. JVM은 코드를 읽어오고, 검증하고, 코드를 실행시키고, 메모리를 관리하고 자바를 실행시킬 수 있는 런타임 환경을 제공한다. 자바 컴파일러는 프로그래머가 작성한 자바 코드를 .class라고 하는 바이트 코드로 전환시킨다. 바이트 코드는 기계어가 아니기 때문에 이 기계어는 JVM위에서 실행되어 자바 프로그램이 실행이된다. 때문에 JVM이 실행이되는 환경이라면 어떤 OS에서도 구애받지 않는다는 장점이 있다. 그 밖의 JVM 특징은 다음과 같다.

  • JVM은 스택 기반 모델: 레지스터 모델과 달리 컴파일이 쉽고 가상머신이 빠르다
  • 심볼릭 래퍼런스: 실제 메모리 주소를 가지는 것이 아닌 Linking 작업을 갖는다.
  • 가비지 컬렉션: 참조 되지 않는 메모리를 회수한다.
  • 기본 자료형의 크기를 명확하게 정의: int같은 자료형의 크기가 플랫폼에 따라 그 크기가 다른데 기본 자료형은 크기를 명확하게 한다.
  • 네트워크 바이트 오더 사용: 바이트 오더는 바이트를 정의하는 방식이고, 네트워크 바이트 오더는 바이트 전송을 위한 바이트 오더 방법이다.

JVM 실행 순서

1) Class Loader: .class파일을 JVM으로 로드 시킨다.
2) Byte Code Verifier: Execute Engine이 Runtime Data Area에 배치되기 전에 ByteCode에 대한 검증 절차를 갖는다.

  • Code가 JVM이 명시한 내용과 일치한가
  • Memory에 허가되지 않은 접근이 존재하는가
  • Stack Over Flow를 체크
  • Data Types 체크
    3) Execution Engine: Load된 바이트코드들을 Runtime Data Areas의 Method Area에 배치한다. class에 정의된 내용대로 바이트 코드를 실행시킨다.
  • Interpreter 방식: 바이트 코드를 한줄씩 해석한다.
  • JIT 방식: 프로그램을 실행하는 시점에 OS에 맞는 Native Code로 변환한다.

JIT(Just In Time Compiler)
자바 프로그램이 실행 되기 위해서 ByteCode는 실시간으로 기계 코드로 해석 되는데, 이와같은 역할은 JIT Compiler가 하게 된다. JIT은 JVM의 일부로 동작 하면서 ByteCode를 필요한 만큼 쪼개어 실시간으로 실행 가능한 상태로 컴파일 한다.

JVM 구조

JVM-Architecture

  • ClassLoader: .class 파일을 메모리에 올린다.
  • MethodArea: 클래스구조같은 메타데이터를 저장한다.
  • Heap: 인스턴스 변수와 관련된 모든 오브젝트가 저장된다.
  • JVM language Stacks: 지역 변수를 저장하고 부분적인 결과를 얻는다. 각 스레드에는 자체 JVM 스택이 있고 스레드가 생성될 때 동시에 생성된다. 메소드를 호출될 때마다 생성되고, 호출 프로세스가 완료되면 삭제한다.
  • PC Registers: 현재 실행중인 Java 가상 시스템 명령의 주소를 저장한다.
  • Native Method Stacks: 네이티브 코드의 지시를 저장한다.
  • Execution Engine: 하드웨어, 소프트웨어 또는 전체 시스템을 테스트하는데 사용되는 소프트웨어의 일종이다.
  • Native Method Interface: 프로그래밍 프레임워크다. JVM에서 실행 중인 Java 코드가 라이브러리 및 네이티브 애플리케이션으로 호출할 수 있도록 한다.
  • Native Method Libraries: 실행 엔진에 필요한 Native Libraries(C, C++)의 모음이다.

JVM 메모리 구조

자바의 메모리 구조는 다음과 같이 구성된다.
JVM-Memory-Model

  • 힙 메모리(Heap Memory)
    힙 메모리영역은 런타임에 할당되는 인스턴스, 배열 등의 모든 자바 클래스의 데이터 영역이다. 힙 메모리는 JVM이 시작시에 생성되고 애플리케이션이 실행되는 동안에 크기가 커지기도 하고 줄어들기도 한다. -Xms를 통해 힙 사이즈를 구체적으로 설정할 수 있다. -Xmx로 최대 힙 크기를 지정할 수 있고 지정하지 않을 시 기본 사이즈는 64MB가 된다.
  • 논힙 메모리(Non-Heap Memory)
    JVM 실행시 생성되어 런타임 상수 Pool, 필드 및 메서드 데이터, 메서드 및 생성자 코드 등 클래스별 구조를 저장한다. 비 heap 메모리의 기본 최대 크기는 64MB이고, 이는 -XX:MaxPermSize VM 옵션을 사용하여 변경할 수 있다.
  • 그밖의 메모리(Other Memory)
    JVM이 사용하기에 필요한 메모리 영역이다. JVM 코드자체를 저장하거나 JVM 내부의 구조 등을 저장하는데 사용된다.

JVM 힙 메모리 구조

JVM 힙 메모리영역은 물리적으로 nursery와 old space 두 영역으로 나뉜다.
HeapMemoryStructure

  • Nursery Part
    • 새 오브젝트가 할당하기 위해 차지하는 공간이다. nursery영역이 가득 찰 경우 special young collection에 의해 죽지않은 오브젝트들을 old space로 옮겨지게 된다. 이 가비지 컬렉션을 Minor GC라고 한다.
  • Old Space
    • Minor GC에도 살아남은 오브젝트들이 있다. 이 곳에서의 가비지 수거는 Major GC로 이루어지고 좀더 시간이 걸린다.
    • 새로 할당된 오브젝트들이 오는 것이 아닌, 비교적 오래 살아남는 오브젝트들이 공간을 차지하게 된다.

Permanent Generation (자바8 이후로는 Metaspace)

애플리케이션에 사용되는 메소드와 클래스들을 설명하는데 필요한 애플리케이션 메타데이터가 포함되어 있다. 런타임에 JVM에 의해 채워진다.
자바8 부터는 Metaspace로 대체되었다. Java Heap에 상주했던 Perm Gen과 달리 힙의 일부가 아니다. 메타스페이스는 OS가 제공하는 범위까지 자동으로 증가시킨다. XX:MetaspaceSize, XX:MaxMetaspaceSize로 크기를 설정할 수 있다.

IBM Memory 영역

HotSpot과 달리 영역이 분리되지 않은 Single Space로 힙이 구성되어 있다. JDK 1.5부터는 Generation 기반의 Heap구조를 지원한다.
새로운 오브젝트들은 Nursery 영역에 생성된다. 만일 새로운 Object가 할당되는데 메모리 영역이 부족한다면 Tenured 영역으로 옮겨지게 된다. Garbage Collection이 옮기기도 한다.
Allocate Space는 최초 오브젝트가 생성될때 할당되는 공간. Allocation Failure가 발생하면 GC가 실행되고 Scavenge가 시작된다. 참조되는 Object들은 Survivor Space로 이동한다. 이후 Allocate와 Survivor의 역할을 바꾸어서 사용한다.

C와 Java 빌드 비교

C

c_execution

1) .c 코드들이 컴파일러에 의해 목적파일로 변환됨
2) 이 목적 파일들을 linker의 도움으로 하나의 .exe파일로 취합한다.
3) 프로그램이 실행되는 동안 이 단일 .exe파일을 메모리에 적재해 실행한다.

Java

java_execution

1) 자바 코드들이 컴파일러에 의해 .class로 된 바이트 코드로 변환된다.
2) C와는 달리 linking 작업이 없다.
3) JVM이 메모리에 올려져있고 실행되는 동안 클래스 로더를 사용하여 클래스 파일이 RAM에 표시된다.

참고

JVM Internal, Naver D2
가상 머신(VM)이란?
[Android] JVM의 스택 기반 모델 vs DVM의 레지스터 기반 모델
Java Memory Management for Java Virtual Machine (JVM)
[Java] JVM - Execution Engine이란?
IBM JVM 튜닝 - 1
JVM | What is Java Virtual Machine & its Architecture

'웹 개발' 카테고리의 다른 글

객체지향 SOLID 원칙  (0) 2021.08.27
객체지향 원리  (0) 2021.08.26
오라클 병렬처리  (0) 2021.04.18
테이블 파티셔닝  (0) 2021.04.11
오라클 아키텍처(Oracle Architecture)  (0) 2021.04.07