java week1, JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.


목차



JVM이란 무엇인가


JAVA Virtial Machine의 약자로 Java Byte Code를 OS에 맞게 해석해주는 역활과 시스템 메모리를 관리한다.

Java compiler는 .java파일을 .class라는 java byte code로 변환한다.

  • byte code는 기계어가 아니기에 os가 실행할 수 없다.

jvm은 byte코드를 이해할 수 있도록 해석해주는 역활을 한다.

  • 기본은 인터프리터 방식으로 한줄 씩 해석하지만 어느정도 양이 됬을때 컴파일하여 실행하고 이를 반복한다.

byte코드는 jvm위에서 os상관없이 실행한다.

  • jvm은 os에 독립적이지만 의존적이다.

컴파일 하는 방법


cmd에서 자바 컴파일 하기

  1. class 파일만들기
    $ javac main.java
    
  2. 파일 실행
    $ java main
    

    java 컴파일 과정

    보통 ide나 terminal환경에서 .java 파일을 생성한다.

build라는 작업을 통해 .class파일을 생성하게 된다.

.class파일은 바이트코드로 기계어가 아니기에 os가 읽을 수 없다.

그림

.class 파일은 클래스 로더에 의해서 jvm 내로 로드 되고, 실행 엔진에 의해 기계어로 해석되어 메모리 상에 배치되게 된다.

실행 엔진에는 InterpreterJIT(Just In Time) Compiler가 있다.

Interpreter는 한 줄씩 코드를 읽어 느리다. 그러나 이 단점은 JIT가 보완한다.

인터프리터 방식으로 실행하다가 적절한 시점에서 바이트 코드 전체를 컴파일 하고 더 이상 인터프리팅 하지 않고 해당 코드를 직접 실행한다. JIT Compiler에 의해 해석된 코드는 캐시에 보관하기 때문에 한 번 컴파일 된 후에는 빠르게 수행하는 장점이 있다.

  • InterPreter 자바 바이트 코드를 한줄 씩 실행, 여러번 실행하는 환경에서는 다소 느림
  • JIT Compiler Interpreter의 단점을 보완, 전체 바이트 코드를 컴파일, 캐시 사용으로 한번 컴파일하면 다음에는 빠르게 수행

실행하는 방법


eclipse

intellij


바이트코드란 무엇인가


바이트코드는 특정 하드웨어가 아닌 가상 컴퓨터에서 돌아가는 실행 프로그램을 위한 이진 표현법이다. 하드웨어가 아닌 소프트웨어에 의해 처리되기 대문에 보통 기계어 보다 더 추상적이다.

JVM이 사용자가 작성한 .java 소스 코드 파일을 운영체제에 실행 가능한 명령어 집합 파일로 컴파일 하는 과정 중에서 필요한 코드

  • jvm이 이해할 수 있는 언어로 변환된 자바 소스코드를 의미
  • 자바 컴파일러에 의해 변환되는 코드의 명령어의 크기가 1byte라서 자바 바이트 코드라고 불림
  • 자바 바이트 코드는 자바 가상 머신만 설치되어 있다면 어느 운영체제에서도 실행 가능

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


프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일 기법이다.

JIT 컴파일러는 실행 시점에서 인터프리트 방식으로 기계어 코드를 생성하면서 그 코드를 캐싱하여, 같은 함수가 여러 분 불릴 때 매번 기계어 코드를 생성하는 것을 방지한다.

즉, 자바 컴파일러가 자바 프로그램 코드를 바이트 코드로 변환한 다음, 실제 바이트 코드를 실행하는 시점에서 자바 가상 머신이 바이트 코드를 JIT 컴파일을 통해 기계어로 번역한다.

JIT 컴파일러의 주요 정의 특성은 프로그램이 시작되고 코드를 컴파일한 후에 JIT 컴파일러를 실행한다는 것이다.

  1. HelloLeaguecat.java 소스 코드를 작성

  2. javac.exe(Java 컴파일러)가 바이트 코드 (HelloLeaguecat.class)로 변환해준다.

  3. JVM에서 각 운영체제에 맞는 기계어로 번역해 전달한다.

그림


JVM 구성 요소


그림

  • class loader runtime 시점에 클래스를 로딩하게 해주며 클래스의 인스턴스를 생성하면 클래스 로더를 통해 메모리에 로드하게 된다.

  • runtime data areas Jvm이 프로그램을 수행하기 위해 os로 부터 별도로 할당 받은 메모리 공간을 말하며, runtime data areas는 크게 5가지 영역으로 나눌 수 있다.

  • execution engine(실행엔진) load된 class의 bytecode를 실행하는 runtime module이 바로 execution engine이다. class loader를 통해 jvm 내의 runtime data areas에 배치된 바이트 코드는 execution engine에 의해 실행된다.

  • Garbage Collector Garbage Collector(GC)는 Heap 메모리 영역에 생성된 객체들 중에 참조되지 않은 객체들을 제거하는 역할을 한다. GC의 동작시간은 일정하게 정해져 있지 않기 때문에 언제 객체를 정리할지는 알 수 없다. 즉 바로 참조가 없어지자마자 작동하는 것이 아니라는 것이다. 또한 GC를 수행하는 동안 GC Thread를 제외한 다른 모든 Thread는 일시정지상태가 된다.

    특히, Full GC가 일어나는 수초간 모든 Thread가 정지한다면 심각한 장애로 이어질 수 있다.

최초 JVM이 나왔을때 Interpreter(한 줄씩 해석하고 실행) 이였기 때문에 속도가 느리다는 단점이 있었지만 JIT compiler (just in time) 방식을 통해 이 점을 보완해왔다. JIT는 bytecode를 어셈블러 같은 nativecode로 바꿔서 실행이 빠르지만 역시 변환하는데 비용이 발생한다. 이 같은 이유 때문에 jvm은 모든 코드를 jit compiler 방식으로 실행하지 않고 interpreter 방식을 사용하다 일정 기준이 넘어가면 jit compiler 방식으로 실행한다.


JDK와 JRE의 차이


JRE(Java Runtime Environment)

자바 애플리케이션의 실행 환경이다. 이미 컴파일된 자바 애플리케이션의 모듈(JAR 파일과 클래스 파일 등)을 이용하여 실행할 수 있다.

JDK(Java Development Kit)

자바 애플리케이션의 개발 환경이다. 실행 환경뿐만 아니라 소스 파일의 컴파일러 및 디버거 등 자바 애플리케이션을 개발하기 위한 도구가 포함되어 있다.

애플리케이션을 JRE가 있으면 작동시킬 수 있다. 단, 운영할때 디버깅 및 분석 등을 하고자 하는 경우에는 jdk에 들어있는 도구가 필요하다. 따라서 서버 등의 운영 환경에 설치하는 경우에도 JRE보다는 JDK를 선택하는 것이 좋은 경우도 있다.

그림






© 2019.04. by salmon2

Powered by theorydb