자바의 실행 과정

이재연·2020년 11월 23일
1

Java Basic

목록 보기
1/15

JVM이란?

Java Virtual Machine. 자바 프로그램을 운영체제, 하드웨어에 상관없이 실행할 수 있게 해주고, 프로그램 메모리를 관리하고 최적화해준다. 자바 바이트코드(.class)를 운영체제에 맞는 시스템 명령어로 번역하여 실행한다.

컴파일 하는 방법

컴파일은 사람이 이해하는 언어를 기계어로 바꾸는 과정이다. 다시 말해 원시코드에서 목적 코드로 바꾸는 과정이다. 자바에서의 컴파일은 자바 소스코드(.java)를 읽어 자바 바이트코드(.class)로 변경하는 것이다.빌드란 소스코드 파일을 실행 가능하게 만들어주는 과정이다.

javac(자바 컴파일러)를 통해 컴파일한다.

$ javac 파일명.java

실행하는 방법

빌드란 소스코드 파일을 실행 가능하게 만들어주는 과정이다.

  • 자바의 실행과정
  1. 자바 컴파일러를 통해 자바 클래스 파일(.java)를 자바바이트코드(.class)로 변환한다.
  2. 클래스 로더를 통해 자바 바이트코드를 JVM 런타임 데이터 역역에 로드한다.
  3. 실행 엔진을 통해 실행한다.

빌드 툴을 통해 실행 가능한 파일로 빌드 한 후에 실행하거나 class 파일을 직접 실행한다.

$ java 파일명

바이트코드란?

바이트코드란 가상 컴퓨터에서 작동하도록 만든 이진코드이다.

자바 바이트코드란 JVM이 이해할 수 있는 언어로 변환된 코드이며 명령어의 크기가 1 바이트라서 자바 바이트코드라고 불린다. 자바 코드를 배포하는 가장 작은 단위이고 확장자는 .class이다.

자바 바이트코드의 명령어는 OpCode와 피연산자(Operand)로 이루어져 있다.

컴파일러의 버전과 JVM 버전이 다르면 컴파일 된 바이트코드가 실행되지 않을수도 있다. 상위 버전에서 컴파일한 바이트코드는 하위 버전에서 실행하지 못한다. 하지만 컴파일 옵션으로 해결 할 수 있다.

JIT 컴파일러란?

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

javac의 컴파일과 JIT의 컴파일은 다르다. 자바컴파일러(javac)는 자바 소스코드를 바이트코드로 변환하고 JIT는 변환된 바이트코드를 해석하고 실행한다.

같은 코드를 매번 해석하지 않고 실행할 때 컴파일 하면서 코드를 캐싱 한다. 사전에 정의된 임계치에서 시작하여 호출될 때마다 감소시키는 방식으로 자주 사용되는 메서드를 찾는다. 자주 사용되는 메서드는 저장해서 해석하지 않고 바로 실행시키는 방식으로 성능을 향상시킨다.

출처 : [https://d2.naver.com/helloworld/1230](https://d2.naver.com/helloworld/1230)

JVM 구성요소

크게 Class Loader, Execution Engine, Runtime Data Area로 구성되어 있다.

출처 : [https://d2.naver.com/helloworld/1230](https://d2.naver.com/helloworld/1230)

  • Class Loader

클래스를 JVM의 메모리에 로드한다. 런타임 데이터 영역에 바이트코드로 배치한다.

읽어 들인 클래스를 검사한다.

클래스에 필요한 메모리를 할당하고, 클래스에서 정의된 필드, 메서드, 인터페이스들을 나타내는 데이터 구조를 준비한다.

클래스의 상수 풀 내 모든 심볼릭 레퍼런스를 다이렉트 레퍼런스로 변경한다.

  • Execution Engine

두 가지 방식을 이용하여 데이터 영역에 배치된 바이트코드를 실행한다. 데이터 영역에서 사용하지 않는 메모리를 해제한다.

  1. 인터프리터 : 바이트코드 명령어를 하나씩 읽어서 해석하고 실행한다.
  2. JIT compiler: 인터프리터 방식에 캐싱 방식을 더해 빠르게 수행한다.
  3. Garbage Collector : 메모리 영역의 메모리를 관리한다.
  • Runtime Data Area

프로그램 수행을 위해 OS에서 할당받은 공간

출처 : [https://hongsii.github.io/2018/12/20/jvm-memory-structure/](https://hongsii.github.io/2018/12/20/jvm-memory-structure/)

PC 레지스터, 스택, 네이티브 메서드 스택은 스레드마다 하나씩 생성되고 힙, 메서드 영역은 모든 스레드가 공유해서 사용한다.

힙(Heap)

프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당하여 사용하는 메모리 영역. New 연산자를 통해 생성한 객체, 인스턴스를 저장하는 공간으로, 가비지 컬렉션 대상이다.

메서드(Method)

클래스, 인터페이스, 필드, 메서드, Static 변수 바이트코드 등을 보관한다.

PC 레지스터(PC Register)

현재 수행 중인 JVM 명령의 주소를 갖는다. 어떤 부분을 어떤 명령으로 실행할지를 기록하며 현재 명령과 주소를 저장한다.

스택(Stack)

메서드 호출 시 생성되는 스레드 수행 정보를 기록한다. 임시 데이터를 저장한다.

네이티브 메서드 스택(Native Method Stack)

자바 외의 언어로 작성된 네이티브 코드를 위한 스택이다. JNI(Java Native Interface)를 통해 호출하는 코드를 수행하기 위한 스택이다.

JDK와 JRE의 차이

JDK는 Java Development Kit의 약자로 자바 통합 개발 환경을 의미한다.

JRE는 Java Runtime Environment의 약자로 자바 실행 환경을 의미하며 JDK에 속해있다. Java9 이후로는 JDK만 배포한다.
출처 : [https://medium.com/@mannverma/the-secret-of-java-jdk-jre-jvm-difference-fa35201650ca](https://medium.com/@mannverma/the-secret-of-java-jdk-jre-jvm-difference-fa35201650ca)

0개의 댓글