Inor

[JAVA] JVM(Java Virtual Machine : 자바 가상 머신의 구조) 본문

Computer Engineering/Java

[JAVA] JVM(Java Virtual Machine : 자바 가상 머신의 구조)

Inor 2017. 7. 11. 16:25

가상 머신(VM)


 가상 머신이란 프로그램을 실행 하기 위한 물리적 머신(컴퓨터)과 유사한 머신을 소프트웨어로 구현한 것이라고 할 수 있습니다. 자바의 목표 였던 WORA(Write Once Run Anywhere)을 구현하기 위해서 JVM(자바 가상 머신)이라는 것을 만들었습니다. 따라서 자바 코드를 컴파일 한 파일은 갖고 있으면 같은 환경의 JVM이 있는 하드웨어에서 해당 코드를 실행 시킬수 있다는 뜻 입니다. JVM 명세를 따르기만 한다면 어떤 벤더든 JVM을 만들어서 배포 할 수 있습니다.



JVM의 특징


  • 스택 기반 : JVM은 레지스터 기반이 아닌 스택 기반의 아키텍처 입니다.
  • 심볼릭 레퍼런스 : 기본 자료형의 경우를 제외한 모든 타입(클래스, 인터페이스)의 경우에 메모리 주소 기반의 참조가 아닌 심볼릭 레퍼런스로 참조 합니다.
  • 가비지 컬렉션(garbage collection) : 클래스 인스턴스의 경우에 사용자에 의해서 생성 되고 가비지 컬렉션에 의해서 자동으로 파괴 됩니다.
  • 기본 자료형을 명확하게 정의해서 플랫폼 독립성을 보장 : c/c++의 경우에는 플랫폼에 따라서 int형의 크기가 변하지만 JVM의 경우에는 기본 자료형을 명확하게 정의하여 호환성을 유지하고 플랫폼 독립성을 보장 합니다.
  • 네트워크 바이트 오더(Network Byte Order) : 자바 클래스 파일은 네트워크 바이트 오더를 사용 합니다. 플랫폼의 독립성을 보장하기 위해서 고정된 바이트 오더를 사용해야 합니다. 그렇기 때문에 JVM의 경우에는 네트워크 전송 시에 사용하는 바이트 오더인 네트워크 바이트 오더를 사용 합니다. 네트워크 바이트 오더는 빅 엔디안 입니다.


JVM의 구조

JVM은 아래와 같은 구조를 갖고 있습니다.


 Java Source는 Java Compiler에 의해서 컴파일 되면 다른 프로그램들 처럼 실행 파일로 변경 되는 것이 아니라 Java Byte Code로 작성된 *.class 형식의 파일로 변경이 됩니다. 그렇게 변경된 java Byte Code는  Class Loader에 의해서 Runtime Data Area에 로드하고 Execution Engine이 Java Byte Code를 해석해서 실행 합니다.

  • Class Loader
 자바는 컴파일 타임이 아닌 런타임에 클래스를 처음으로 참조할때 로드하고 링크하는 동적 로드를 하는 특징이 있는데 이것을 담당하는 부분이 Class Loader 입니다. 클래스 로더는 몇 가지 특징을 갖고 있습니다. 부트스트랩 클래스 로더부터 사용자 정의 클래스 로더까지 계층적인 구조로 부모-자식 관계를 구성하고 있습니다. 클래스 로더에대한 자세한 사항은 추후에 살펴보도록 하겠습니다.

  • Execution Engine
 자바 실행 엔진으로 Class Loader에 의해서 Runtime Data Area에 로드 된 Java Byte Code를 실행 시키는 역할을 수행하는 곳 입니다. Java Byte Code는 어느정도 사람이 보기 편한 방식으로 기술이 된 것 입니다. 이것은 Execution Engine을 통해서 JVM 내부의 기계가 이해 할 수 있는 형태로 변경하는 역할을 합니다. 변경하는 방식에는 Interpreter와 JIT(Just In Time)이 있습니다.

  • Runtime Data Area


  프로그램을 실행하기 위해서 OS로 부터 할당 받은 메모리 영역 입니다. Runtime Data Area는 Java Application, 특히 WAS(Web Application Server)을 사용할때 성능 문제를 일으키는 부분이기도 합니다.(Memory Leak, Garbage Collection)

  • PC Register : 현재 수행중인 JVM 명령의 주소를 갖고 있는 공간으로 하나의 스레드가 생성될 때마다 생성 됩니다. 프로그램의 실행은 CPU에서는 명령어(즉, Instruction)를 실행하는 과정으로 진행이 되는데 이러한 Instruction을 수행하는 동안 필요한 정보를 저장하는 공간을 레지스터라고 하는 CPU 내의 기억장치를 사용 합니다.
  • JVM Stack : 각 스레드마다 하나씩 존재 하며 JVM은 스택 프레임(Stack Frame)이라는 구조체를 추가(Push), 제거(Pop) 하는 동작만을 수행 합니다. 지역 변수 배열. 피연산자 스택, 현재 메서드가 실행중인 런타임 상수 풀에대한 레퍼런스를 갖고 있습니다.
  • Native Method Stack : 자바 이외의 코드로 작성된 네이티브 코드를 위한 스택 입니다.
  • Method Area : 모든 스레드가 공유하는 공간으로 JVM이 실행 될 때 생성 됩니다. JVM이 읽어들인 각각의 클래스와 인터페이스에 대한 Runtime Constant Pool, 필드와 메서드 정보, Static 변수, 메서드의 바이트 코드 등을 보관 합니다. JVM 벤더마다 다양하게 구성 할 수 있으며 Method Area에 대한 가비지 컬렉션 또한 벤더의 선택 사항 입니다.
  • Runtime Constant Pool : Method Area에 속한 영역이긴 하지만 JVM 동작에서 핵심적인 역할을 수행하는 곳 입니다. 각 클래스와 인터페이스의 상수 뿐만 아니라 메서드와 필드들의 모든 레퍼런스를 저장하고 있는 공간 입니다. 특정 메서드나 필드를 참조 할때 JVM은 Runtime Constant Area를 통해서 메서드나 필드의 실제 메모리상 주소를 찾아서 참조 합니다.
  • Heap : 객체를 저장하고 있는 공간으로 가비지 컬렉션의 대상이 되는 공간 입니다. JVM의 성능 이슈에서 가장 많이 언급되는 공간으로 구성 방식과 가비지 컬렉션 방식은 JVM 벤더의 재량 입니다. 모든 스레드가 공유하는 공간 입니다.

    • Youg Generation : 생성된 객체는 Young Generation에 저장 됩니다. 객체가 생성된 후 오랜 기간이 지나고 우선 순위가 낮아진 객체는 Old Generation으로 이동이 됩니다.
    • Old Generation : 생성된지 오래된 객체가 Young Generation에서 Old Generation으로 이동 됩니다. 생성된지 오래된 객체가 저장되는 영역
    • Perm : Class, Method 등의 코드가 저장되는 영역으로 JVM에 의해서 사용되는 영역 입니다.

참조


Comments