🎯 공부 목표

  • 자바 소스파일(.java)을 JVM으로 실행하는 과정 이해하기

 

학습할 것

  • JVM이란 무엇인가
  • 컴파일 및 실행 하는 방법
  • 바이트코드란 무엇인가
  • JIT 컴파일러란 무엇이며 어떻게 동작하는지
  • JVM 구성 요소
  • JDK와 JRE의 차이

1️⃣ JVM이란 무엇인가

 

🔗 참고자료

 

 

 

출처: 부스트코스(쉽게 배우는 자바1)

 

# JVM 이란?

 

자바 가상 머신(Java Virtual Machine)은 자바 바이트코드를 실행, 해석할 수 있는 주체이다.

JVM의 역할은 자바 애플리케이션을 클래스 로더(Class Loader)를 통해 읽어 들여서 자바 기본 API를 동적으로 연결해 자바 프로그램을 실행하는 것입니다.

  • 기술적 정의
    -> 코드를 실행하고 해당 코드에 대해 런타임 환경을 제공하는 소프트웨어 프로그램에 대한 사양(Specification)

  • 일반적 정의
    -> JVM은 자바 프로그램을 실행하는 방법이다. JVM의 설정을 구성한 다음 설정 사항에 따라 실행 중에 프로그램 리소스를 관리한다.

 

* 가상 머신 : 프로그램을 실행하기 위해 물리적 머신과 유사한 머신을 소프트웨어로 구현한 것.

 

#JVM의 특징

 

  • 스택 기반의 가상 머신
    -> 대표적인 컴퓨터 아키텍처인 인텔 x86 아키텍처나 ARM 아키텍처와 같은 하드웨어가 레지스터 기반으로
    동작하는 데 비해 JVM은 스택 기반으로 동작한다.

  • 심볼릭 레퍼런스(Symbolic Reference)
    -> 기본 자료형(primitive data type)을 제외한 모든 타입(클래스와 인터페이스)을 명시적인 메모리 주소 기반의
    레퍼런스가 아니라 심볼릭 레퍼런스를 통해 참조한다.

  • 가비지 컬렉션(Garbage collection)
    -> 클래스 인스턴스는 사용자 코드에 의해 명시적으로 생성되고 가비지 컬렉션에 의해 자동으로 파괴된다.

  • 기본 자료형을 명확하게 정의하여 플랫폼 독립성 보장
    -> C/C++ 등의 전통적인 언어는 플랫폼에 따라 int 형의 크기가 변한다. JVM은 기본 자료형을 명확하게 정의하여
    호환성을 유지하고 플랫폼 독립성을 보장한다.

  • 네트워크 바이트 오더(Network byte order)
    -> 자바 클래스 파일은 네트워크 바이트 오더를 사용한다. 인텔 x86 아키텍처가 사용하는 리틀 엔디안이나,
    RISC 계열 아키텍처가 주로 사용하는 빅 엔디안 사이에서 플랫폼 독립성을 유지하려면 고정된 바이트 오더를 유지해야 하므로 네트워크 전송 시에 사용하는 바이트 오더인 네트워크 바이트 오더를 사용한다.
    네트워크 바이트 오더는 빅 엔디안이다.

  • Class 파일은 JVM이 읽을 수 있는 형태로 번역된 결과물이다.
  • Class 파일은 참조하는 라이브러리를 포함하지 않고 단순히 심볼릭 레퍼런스만을 가진다.

 

 

 

# 자바 바이트 코드(ByteCode)

WORA(Write Once Run Anywhere) 를 구현하기 위해 JVM은 사용자 언어인 자바와 기계어 사이의 중간 언어인 자바 바이트 코드를 사용한다.

이 자바 바이트코드가 자바 코드를 배포하는 가장 작은 단위이다.

 

  • ByteCode는 JVM을 위한 언어이다.

 

 

 

# 심볼릭 레퍼런스란?

심볼릭 레퍼런스는 참고하는 클래스의 특정 메모리 주소를 참조 관계로 구성한 것이 아니라 참조하는 대상의 이름만을 지칭한 것이다.

Class 파일이 JVM에 올라가게 되면 심볼릭 레퍼런스는 그 이름에 맞는 객체의 주소를 찾아서 연결하는 작업을 수행한다.

실제 메모리 주소가 아니라 이름만을 가진다.

 

 

 


2️⃣ 컴파일 및 실행 하는 방법

 

 

🔗 참고자료

 

 

 

# 자바로 작성된 코드 실행 전 필수사항

자바로 작성된 코드를 컴파일해서 자바 Bytecode를 생성하기 위해서는 JDK가 필수로 설치되어 있어야 합니다.

 

 

JDK(Java Development Kit)란?

자바 개발 키트로 자바 애플리케이션을 구축하기 위한 핵심 플랫폼 구성요소입니다.

이 중심에는 자바 컴파일러(Compiler)가 있습니다.

 

JDK는 JVM, JRE과 함께 자바 프로그래밍에 사용되는 3대 핵심 기술 패키지 가운데 하나입니다.

 

  • JVM : 프로그램을 실행하는 자바 플랫폼 구성요소
  • JRE : JVM을 생성하는 디스크 상의 부분
  • JDK : 개발자들이 JVM과 JRE에 의해 실행되고 구동될 수 있는 자바 프로그램을 생성할 수 있게 해 준다.

 

위 사진을 보면 알 수 있듯이 JDK를 설치하면 JRE, JVM도 설치가 됩니다.

 

 

 

설치 및 환경변수 설정 방법

https://mozi.tistory.com/428

 

[JAVA] OpenJDK 다운로드 및 설치하기 (JDK 다운 및 설치하기, JDK 란, 환경변수 잡는법)

JDK (Java Development Kit) 란 JAVA 언어로 개발 및 빌드하기 위한 '개발 툴킷' 을 의미합니다. JDK 는 JRE 기능을 포함하고 있으며, 자바프로그램이 JVM 에 의해 실행할 수 있도록 해줍니다. JDK 와 OpenJDK..

mozi.tistory.com

 

 

 

# 개발도구 없이 자바 소스코드 컴파일(Window)

 

openJDK를 설치했다면 해당 경로에 보면 bin 디렉터리가 있습니다.

 

* bin  디렉터리에는 자바로 개발하는데 필요한 주요 파일들이 들어있습니다.

 

 

  1. java.exe : 자바 응용 프로그램 로더.
    -> javac 컴파일러가 만든 클래스 파일을 해석 및 실행한다. 현재 하나의 런처가 개발 및 배포에 동일하게 사용된다. 예전에 사용되던 배포용 런처 jre는 더 이상 Sun JDK에서는 제공되지 않고, 이 로더로 대체되었다.
    * 한 줄 정리 => 자바 인터프리터, 바이트코드를 실행한다.
  2. javac.exe : 자바 컴파일러. 자바 소스 파일을 바이트코드로 변환해준다.
  3. javap.exe : 클래스 파일을 자바 소스 코드로 디스어셈블해주는 도구

 

 

# 본격적으로 자바 소스코드 작성 후 컴파일해보기

 

class HelloWorld
{
	public static void main(String[] args) {
		System.out.println("Hello World!!");
	}
}

 

- 우선적으로 해당 소스 코드를 아래와 같이 메모장에 작성합니다.

 

 

 

 

 

- 작성 완료 후 C 드라이브에 HelloWorld라는 폴더를 만듭니다.

 * 폴더 이름을 꼭 HelloWorld로 할 필요는 없습니다. 원하시는 이름으로 만들어주세요.

 

 

 

 

- 폴더를 만들었으면 해당 폴더에 메모장 파일을 .Java 확장자로 저장합니다.

 꼭 .Java 확장자로 저장을 해야 합니다.

 

 

 

 

저장을 완료했으면 cmd 창을 열어 위와 같이 입력합니다.

 

 

  1. cmd창 명령어인 cd(Change Directory) 명령어를 사용해 해당 경로 이동
  2. javac 명령어를 통해 자바 소스 파일을 자바 바이트코드로 변환합니다.
    => .class 파일 생성
  3. javac 컴파일러가 만든 클래스 파일을 java 명령어를 통해 해석 및 실행한다.
    => 위 사진에서 볼 수 있듯이 Hello World 가 출력된 모습을 확인할 수 있습니다.

 


3️⃣ 바이트코드란 무엇인가

 

 

🔗 참고자료

 

 

# 바이트 코드란?

  • 특정 하드웨어가 아닌 가상 컴퓨터에서 돌아가는 실행 프로그램을 위한 이진 표현법이다.
  • 하드웨어가 아닌 소프트웨어에 의해 처리되기 때문에, 보통 기계어보다 더 추상적이다.
  • 특정 하드웨어에 대한 의존성을 줄이고, 인터프리팅도 쉬운 결과물을 생성하고자 하는 프로그래밍 언어에 의해,
    출력 코드의 한 형태로 사용된다.
  • 컴파일되어 만들어진 바이트코드는 특정 하드웨어의 기계 코드를 만드는 컴파일러의 입력으로 사용되거나, 가상 컴퓨터에서 바로 실행된다.
  • 사람이 읽기 쉽도록 쓰인 소스 코드와 비교하면 바이트 코드는 덜 추상적이며, 더 간결하고, 더 컴퓨터 중심적이다.

 

 

# 자바 바이트 코드란?

자바 컴파일러를 통해 자바 가상 머신이 이해할 수 있는 언어로 변환된 자바 소스 코드를 의미합니다.

자바 바이트 코드는 자바 가상 머신(JVM)만 설치되어 있으면, 어떤 운영체제에서라도 실행 될 수  있습니다.

 

  • 자바 바이트코드는 JVM이 실행하는 명령어의 집합
  • 컴파일하면 생성되는 .class 파일이 바이트 코드를 담고 있습니다.
  • OS나 개발환경에 관계없이 명령어 집합을 사용 할 수 있다.
    -> 자바의 크로스 플랫폼 동작 가능

 

# 자바 바이트 코드를 더 깊게 알려주는 사이트

https://iamsang.com/blog/2012/08/19/introduction-to-java-bytecode/

 

이상현 IN 베를린 :: 자바 바이트코드 소개

자바 바이트코드 소개 Understanding bytecode and what bytecode is likely to be generated by a Java compiler helps the Java programmer in the same way that knowledge of assembly helps the C or C++ programmer. - IBM developerWorks journal 개발을

iamsang.com

 

  • 자바 바이트 코드를 공부하는 이유
  • 자바 바이트 코드 명령어
  • 소스 코드가 자바 바이트 코드로 변환된 결과
    -> if와 switch 문의 차이를 자바 바이트 코드로 분석

해당 링크에 위의 내용 외에도 다양한 내용이 담겨 있습니다.

자바 바이트 코드를 더욱 깊게 알아보고 싶으신 분들은 읽어 보시는 걸 추천드립니다.

 


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

 

 

🔗 참고자료

 

 

# JIT 컴파일러(Just-In-Time compiler)란?

프로그램이 실행 중인 런타임에 실제 기계어로 변화해 주는 컴파일러를 의미합니다.

동적 변환(Dynamic translation)이라고도 불리는 이 기법은 프로그램의 실행 속도를 향상시키기 위해 개발되었습니다.

즉, JIT 컴파일러는 자바 컴파일러가 생성한 자바 바이트 코드를 런타임에 바로 기계어로 변환하는 데 사용합니다.

 

자바 바이트 코드는 기계가 바로 수행할 수 있는 언어보다는 비교적 인간이 보기 편한 형태로 기술된 것이다.

그래서 실행 엔진은 이와 같은 바이트코드를 실제로 JVM 내부에서 기계가 실행할 수 있는 형태로 변경하며, 그 방식은 다음 두 가지가 있다.

 

 

인터프리터

  • 바이트코드 명령어를 하나씩 읽어서 해석하고 실행한다.
  • 하나씩 해석하고 실행하기 때문에 바이트코드 하나하나의 해석은 빠른 대신,
    인터프리팅 결과의 실행은 느리다는 단점을 가지고 있다.
  • 바이트코드라는 '언어'는 기본적으로 인터프리터 방식으로 동작한다.

 

JIT(Just-In-Time) 컴파일러

  • 인터프리터의 단점을 보완하기 위해 도입된 것이 JIT 컴파일러이다.
  • 인터프리터 방식으로 실행하다가 적절한 시점에 바이트코드 전체를 컴파일하여 네이티브 코드로 변경하고,
    이후에는 해당 메서드를 더 이상 인터프리팅하지 않고 네이티브 코드로 직접 실행하는 방식이다.
  • 네이티브 코드를 실행하는 것이 하나씩 인터프리팅하는 것보다 빠르고,
    네이티브 코드는 캐시에 보관하기 때문에 한 번 컴파일된 코드는 계속 빠르게 수행되게 된다.

 

 

 

 

 


4️⃣ JVM 구성요소

 

🔗 참고자료

 

 

 

# JVM 구조 및 구성

자바로 작성한 코드는 다음 그림과 같은 과정을 통해 수행된다.

출처: NVER D2

 

클래스 로더(Class Loader)가 컴파일된 자바 바이트코드를 런타임 데이터 영역(Runtime Data Areas)에 로드하고,
실행 엔진(Excution Engine)이 자바 바이트코드를 실행한다.

 

 

  1. Class Loader(클래스 로더)
    - JVM내로 클래스(.class파일)를 로드하고, 링크를 통해 치하는 작업을 수행하는 모듈이다.
    - Runtime 시에 동적으로 클래스를 로드한다.
    - jar파일 내 저장된 클래스들을 JVM위에 탑재하고 사용하지 않는 클래스들은 메모리에서 삭제한다.
    - (컴파일러 역할) 자바는 동적 코드, 컴파일 타임이 아니라 런타임에 참조한다.
      즉, 클래스를 처음으로 참조할 때, 해당 클래스를 로드하고 링크한다는 것이다.

  2. Execution Engine(실행 엔진)
    - 클래스를 실행시키는 역할이다.
    - 클래스 로더가 JVM내의 런타임 데이터 영역에 바이트 코드를 배치시키고, 이것은 실행 엔진에 의해 실행된다.
    - 자바 바이트코드는 기계가 바로 수행할 수 있는 언어보다는 비교적 인간이 보기 편한 형태로 기술된 것이다.
    - 실행 엔진은 이와 같은 바이트코드를 실제로 JVM내부에서 기계가 실행할 수 있는 형태로 변경한다.

  3. Interpreter(인터프리터)
    실행 엔진은 자바 바이트 코드를 명령어 단위로 읽어서 실행한다.
    하지만 이 방식은 인터프리터 언어의 단점을 그대로 갖고 있다. 한 줄씩 수행하기 때문에 느리다는 것이다.

  4. JIT(Just - In - Time)
    - 인터프리터 방식의 단점을 보완하기 위해 도입된 JIT 컴파일러이다.
    - 인터프리터 방식으로 실행하다가 적절한 시점에 바이트코드 전체를 컴파일하여 네이티브 코드로 변경하고,
    이후에는 해당 더 이상 인터프리팅 하지 않고 네이티브 코드로 직접 실행하는 방식이다.
    - 네이티브 코드는 캐시에 보관하기 때문에 한 번 컴파일된 코드는 빠르게 수행하게 된다.
    - JIT컴파일러가 컴파일하는 과정은 바이트코드를 인터프리팅하는 것보다 훨씬 오래걸리므로 한번만 실행되는 코드라면 컴파일하지 않고 인터프리팅 하는 것이 유리하다.
    - JIT 컴파일러를 사용하는 JVM들은 내부적으로 해당 메서드가 얼마나 자주 수행되는지 체크하고, 일정 정도를 넘을 때에만 컴파일을 수행한다.

    * 네이티브 코드언매니지드 코드라고도 불립니다. 코드가 바로 Machine Code로 컴파일되고, 컴파일한 Machine과 동일한 칩 등을 사용하는 환경에서만 실행이 가능합니다.(예를 들면 C언어)

 


4️⃣ JDK와 JRE의 차이(자바 기초스터디 1 - 6)

 

🔗 참고자료

 

 

# JRE(Java Runtime Environment) 란?

JVM(자바 가상 머신), 자바 클래스 라이브러리(Java class library), 자바 명령(Java command) 및 기타 인프라를

포함한 컴파일된 자바 프로그램을 실행하는데 필요한 패키지이다.

 

  • 자바 애플리케이션을 생성하고 실행하기 위한 일련의 구성 요소입니다.
  • JDK(Java Development Kit)의 일부입니다.
  • JVM, 자바 클래스 라이브러리, 자바 클래스 로더로 구성됩니다.

 

JRE의 용도

  • 자바 소프트웨어 개발에 사용되고, 프로그래밍 툴 및 배포 기술을 제공합니다.
  • JRE는 JDK를 사용하여 작성된 자바 코드를 JVM에서 이의 실행에 필요한 필수 라이브러리와 결합한 후
    결과 프로그램을 실행하는  JVM의 인스턴스를 작성합니다.
  • JVM은 다수의 운영체제에 사용 가능하며, JRE를 사용하여 작성된 프로그램이 모든 운영체제에서 실행됩니다.

 

 

 

# JDK(Java Development Kit)란?

자바 개발 키트로 자바 애플리케이션을 구축하기 위한 핵심 플랫폼 구성요소입니다.

이 중심에는 자바 컴파일러(Compiler)가 있습니다.

 

JDK는 JVM, JRE과 함께 자바 프로그래밍에 사용되는 3대 핵심 기술 패키지 가운데 하나입니다.

 

 

 

# JDK 와 JRE의 차이점

JDK : Standard Edition, Enterprise Edition 및 Micro Edition과 같은 자바 플랫폼에서 자바 응용프로그램을 개발하는 데 사용되는 소프트웨어 개발 환경입니다.

JRE : 자바 응용 프로그램을 실행하는 데 필요한 최소 요구 사항을 제공하는 JDK의 일부입니다.

 

 

JDK와 JRE의 차이점은 JDK는 자바 프로그램을 개발하고 실행할 수 있는 환경을 제공하는 반면

JRE는 자바 프로그램을 실행하는 환경 만 제공한다는 것입니다.

 

요약 => JDK는 JDE와 개발 도구의 조합, JRE는 JVM과 라이브러리 파일의 조합입니다.

반응형

+ Recent posts