JVM

Bong2·2022년 2월 5일
1

JAVA

목록 보기
2/16
post-thumbnail

JVM이란 무엇인가

정의 : JVM은 Java Virtual Machine의 줄임말로 어느 환경(Mac, Linux)이던지 자바 프로그램을 실행할 수 있도록 도와주는 프로그램


컴파일 하는 방법

javac fileName.java

컴파일 과정

  1. .java파일을 생성한다.
  2. build를 한다.
  3. java compiler의 javac의 명령어를 통해 바이트코드(.class)를 생성
  4. class loader를 통해 jvm내로 로드
  5. 실행 엔진을 통해 컴퓨터가 읽을 수 있는 기계어로 해석된다

실행하는 방법

java fileName.class
  • jvm의 구성요소인 클래스 로더가 fileName.class 파일을 메모리상의 JVM으로 가져온다.
    classLoader -> Byte Code Verifier -> Exeuction Engine ( 클래스파일을 기계어로 변경해서 명령어 단위로 실행)

명령어 단위 실행

  1. Interpreter : 명령어를 하나씩 수행하는 방식
  2. JIT(Just in Time compiler) : 전체 바이트코드를 네이티브 코드로 변환하고 그 이후에는 네이티브 코드로 실행하는 방식

Interpreter vs compiler

  • Interpreter
  1. 프로그램 Runtime실행시간에 한번에 한 문장씩 변환.
  2. 소스 코드를 분석하는데 걸리는 시간은 적지만 전체 실행 시간은 compiler로 변환한 코드보다 상대적으로 더 느리다
  3. 중간 Object Code(목적코드)가 만들어지지 않아 메모리 효율이 높다
  4. 첫 오류를 만날때 까지 프로그램을 계속 번역하고 오류를 만나면 중지
  5. Python Ruby와 같은 언어

바로 machine code로 변환되는 것이 아니라 Interperter가 해석할 수 있는 Bytecode라는 machine code보다 추상적인 이진 표현법으로 먼저 변환 후 이 Bytecode를 interpreter가 변환하여 machine code로 변환한다.

  • compiler
  1. 프로그램 Runtime전에 전체 소스코드를 검사하여 machine code로 변환
  2. 소스코드를 분석하는데 많은 시간이 들지만 전체 실행시가능은 interperter로 변환한 코드보다 비교적 빠르다
  3. 링킹을 추가로 필요로 하는 중간 Object Code를 생성하여 더 많은 메모리를 필요로 한다.
  4. 전체 코드를 검사한 후에 오류 메시지를 생성한다. 그래서 실행 전에 오류를 발견할 수 있다.
  5. C, C++, Java와 같은 언어

Object Code : 컴파일러나 어셈블러가 소스 코드 파일을 이진 코드로 변환하여 생성하는 파일

링킹 : 여러 개의 Object file을 하나의 실행할 수 있는 프로그램으로 만드는 작업

바이트코드란 무엇인가

  • 자바 가상머신이 이해할 수 있는 언어로 변환된 자바 소스코드, 자바 컴파일러로 변환되는 코드의 명령어 크기가 1바이트라서 바이트 코드라고 불린다.


    자바는 OS에 종속적이지 않기 위해서 JVM이 이해할 수 있는 언어인 바이트코드 형태로 제공

JIT 컴파일러란 무엇이며 어떻게 동작하는지

JIT 컴파일러란?

기존 클래스파일(바이트코드)를 실행하는 방법은 Interpreter방식이 기본이다.
명령어 실행속도는 빠르지만 전체 코드 관점에서 보면 실행 속도가 느린 단점을 해결하기 위해서 JIT 등장
JIT 컴파일러는 런타임시 클래스파일을 네이티브 기계어로 한방에 컴파일 후 사용하는 개념

전체 컴파일 후 캐싱 -> 이후 변경된 부분만 컴파일하고 나머지는 캐시에서 가져다가 바로 실행 이다. 바로 꺼내서 사용하고 변경 부분만 컴파일 하기 때문에 코드 수행속도가 Interpreter 방식에 비해서 빠르다!


JVM 구성 요소

크게 4가지 구성으로(Class Loader, Execution Engine, Garbage Collector, Runtime Data Area) 나누어 집니다.

class loader

자바 컴파일러에 의해 바이트코드로 변환된 클래스를 읽어들여 Runtime Data Area 에 적재하는 역할을 합니다.

execution Engine

Class Loader 에 의해 Runtime Data Area 에 적재된 클래스(바이트코드) 를 기계어로 변환하고 실행하는 역할을 합니다.

Garbage Collector

Garbage Collector(GC) 는 Heap 영역에 생성되어 있는 객체들 중 참조되지 않는 객체를 찾아 제거하는 역할을 합니다.

GC 가 실행되는 시간은 정해져 있지 않습니다. 특히 Full GC 가 발생하는 경우, GC 를 제외한 모든 스레드가 중지되기 때문에 장애가 발생할 수 있습니다.

Runtime Data Area

JVM 의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역입니다.

Runtime Data Area 상세

Method Area

클래스 정보가 저장되는 공간입니다.

클래스의 메소드 정보가 저장되고, 맴버 변수의 이름과 타입, 메소드의 이름과 파라미터 그리고 리턴값이 저장되고, 각종 상수, static 메소드, final 클래스 변수 등이 저장됩니다.

Heap Area

new 키워드에 의해 생성되는 클래스와 배열 등이 저장됩니다.

Method Area 영역에 저장된 클래스만이 생성 가능하고, Garbage Collector 에 의해 사용되지 않는 클래스/배열이 제거됩니다.

Stack Area

지역 변수, 파라미터, 리턴 값, 연산에 사용되는 임시 값등이 생성되는 영역입니다.

int 와 같은 클래스 아닌 변수들은 이곳에 저장됩니다. Person p = new Person(); 와 같이 클래스를 생성할 경우, new 에 의해 생성된 클래스는 Heap Area 에 저장되고, Stack Area 에는 생성된 클래스의 참조인 p 만 저장됩니다.

클래스의 메소드를 실행할 때마다 스택이 생성됩니다.

Method Area, Heap Area 를 제외한 영역들은 스레드간에 공유되지 않습니다.

PC Register

스레드가 생성될 때마다 생성되며, 현재 실행중인 주소와 명령을 저장합니다.

멀티 스레드가 동작할 때, 이곳의 정보를 이용해 여러 스레드를 동시에 실행할 수 있습니다.

Native Method Stack

자바 이외의 코드(JNI) 가 저장되는 공간입니다.

Heap area & Garbage Collector


Heap area 는 eden, survivor1, survivor2, old, permanent 로 5개로 구성됩니다.

Minor GC

최초에 객체는 모두 eden 에 생성됩니다.

eden 영역이 가득차게 되면 첫번째 GC(Minor GC) 가 발생합니다. survivor1 영역으로 eden 영역의 메모리를 그대로 복사합니다. 그리고, survivor1 영역을 제외한 다른 영역의 객체를 제거합니다.

eden 영역과 survivor1 영역이 모두 가득차게되면, 참조되고 있는 객체를 찾아 모두 survivor2 로 복사합니다. survivor2 를 제외한 나머지 영역의 객체를 모두 제거합니다.

위 과정을 반복하고, survivor2 가 가득차기 전에 old 영역으로 다시 복사를 진행합니다.

Major GC(Full GC)

old 영역을 검사하여 참조가 없는 객체들을 찾아 모두 제거합니다.

이렇게 하면 메모리 영역에 중간중간 구멍(제거되고 빈 메모리 공간) 이 생기는데, 이것을 디스크 조각모음처럼 조각난 메모리를 정리합니다.

모든 메모리를 이동시키기에 다른 스레드가 접근할 수 없도록 모든 스레드를 정지시킵니다.


JDK와 JRE의 차이

JDK

Java 프로그램을 개발하고 실행할 수 있는 환경을 제공
프로그램을 생성하고 컴파일

JRE

java관련 파일이 있는 디렉터리( bin,conf,lib)
Java 프로그램을 실행하는 화면만 제공
자바 가상 머신, 자바 클래스 라이브러리, 자바 명령 및 기타 인프라를 포함한 컴파일된 Java프로그램을 실행하는데 필요한 패키지

profile
자바 백엔드 개발자로 성장하자

0개의 댓글