Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

공부를 하자

Week-01-JVM 본문

개발/자바

Week-01-JVM

Jade✨ 2021. 4. 13. 03:29

1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.

1. JVM이란 무엇인가

JVM(Java Virtual Machine)

JVM(Java Virtual Machine)이란 자바 바이트 코드를 실행시키기 위한 가상의 기계라고 할 수 있다. 자바 바이트코드.class를 OS에 맞게 해석, 실행해준다.

자바로 작성된 모든 프로그램은 자바 가상머신에서만 실행될 수 있으므로, 자바 프로그램을 샐행하기 위해서는 반드시 자바 가상 머신이 설치되어 있어야 한다.

JVM의 특성

  • 플랫폼(OS)에 의존적
  • 스택 기반의 가상 머신
  • 단일 상속 형태의 객체 지향 프로그래밍을 가상 머신 수준에서 구현
  • 포인터를 지원하되 포인터 연산(C와 같이 주소 값을 임의로 조작)이 불가능
  • 가비지 컬렉션(Garbage collection) 사용
    • Garbage collection: 메모리 관리 기법 중의 하나로 프로그램이 동적으로 할당했던 메모리 영역 중에서 필요없게된 영역(어떤 변수도 가리키지 않게 된 영역)을 해제하는 기능
  • 모든 기본 타입의 정의를 명확히 함으로써 플랫폼 독립성 보장
  • 데이터 흐름 분석(data flow analysis)에 기반한 자바 바이트코드 검증기를 통해 스택 Overflow, 명령어 피연산자의 타입 규칙 위반, 필드 접근 규칙 위반, 지역 변수의 초기화 전 사용 등 많은 문제를 실행 전에 검증하여 실행 시 안전을 보장하고 별도의 부담을 줄여줌
  • 명령어에서 스택에서 가져올 피연산자의 타입을 명령어에 지정(예: 정수 덧셈은 iadd, 단정밀도 실수 덧셈은 fadd)

Write once, run anywhere

일반 애플리케이션은 OS와 바로 맞붙어 있어 OS에 종속적이지만, Java 애플리케이션은 JVM과 상호작용을 하기 때문에 OS와 하드웨어에 독립적이다.

단, JVM은 OS에 종속적이기 때문에 OS에 맞는 JVM이 필요하다.

2. 컴파일 및 실행 방법

자바 프로그램을 실행시키는 과정

img

이미지 출처: https://wikidocs.net/887

1) 자바 설치

  • command Prompt(cmd.exe)를 실행하여 자바 설치 확인
  • cmd에서 java -version 입력

cmd java version 확인

2) 자바 파일 생성: 사용 가능한 텍스트 에디터를 통해 다음과 같은 자바 파일을 생성, 파일명은 MyClass.java

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

3) 자바 파일 컴파일

  • cmd에서 자바파일을 생성한 경로로 이동한 후javac MyClass.java 입력, 아래와 같이 .class 파일이 생성된 것을 확인할 수 있음

java file compile

4) 자바 파일 실행

  • cmd에서 java MyClass.java 실행, 그럼 다음과 같이 Hello World가 출력된 것을 확인할 수 있음

3. 바이트코드란 무엇인가

이미지 출처: https://www.eginnovations.com/blog/how-to-troubleshoot-java-code/

바이트코드(Bytecode)는 고급 언어로 작성된 소스 코드를 JVM이 이해할 수 있는 코드로 컴파일한 것이다.

자바 바이트코드는 플랫폼에 독립적이며, JVM 위에서 OS 상관없이 실행된다.

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

JIT(Just-In-Time)

실행 시점에 코드를 기계어로 변환하면서(인터프리트방식) 캐시에 저장하여, 재사용할 때 이미 변환된 기계어 코드를 재사용하는 방식이다.

전통적인 컴파일 방식(인터프리트 방식, 정적 컴파일 방식)의 단점을 보완하기 위해 두 가지 방식을 혼합하여 사용한다.

  • 인터프리트 방식의 단점: 바이트코드나 소스코드를 최적화 과정 없이 번역하기 때문에 성능이 낮음
  • 정적 컴파일 방식: 실행 전에 무조건 컴파일을 해야하기 때문에 다양한 플랫폼에 맞게 컴파일을 하려면 시간이 오래 걸림

JIT는 정적 컴파일러 만큼 빠르면서 인터프러터 언어의 빠른 응답속도를 추구

5. JVM 구성 요소

크게 Class Loader, Runtime Data Areas, Excution Engine 3가지로 구성되어 있다.

JVM 구조

1) Class Loader

클래스 로더는 클래스 파일을 로드하는데 사용되는 JVM의 하위 시스템이다. 자바 컴파일러를 통해 생성된 바이트 코드(.class)를 엮어 Runtime Data Area 형태로 메모리에 적재하는 역할을 수행하며, 자바 클래스 로더는 세가지 타입으로 구성되어 있다.

  • Bootstrap ClassLoader : 첫 번째 클래스로더로, Extension ClassLoader의 조상클래스이자 모든 클래스로더의 최상위 조상이다. $JAVA_HOME/jre/lib/rt.jar에 위치한 기본적인 클래스(예: java.lang, java.net, java.util, java.io package classes 등)를 로드한다. Bootstrap ClassLoader는 Java가 아닌 C나 C++과 같은 네이티브 코드로 구현되어 있다는 점이 특징이다.
  • Extension ClassLoader : BootStrap ClassLoader의 자손클래스이자 System ClassLoader의 조상클래스로 $JAVA_HOME/jre/lib/ext 디렉토리에 위치하는 jar 파일들을 로드한다.
  • System/Application ClassLoader : Extension ClassLoader의 자손클래스로, classpath에 위치한 클래스파일들을 로드한다. 기본적으로 CLASSPATH 환경변수로 설정된 위치에 있는 클래스 파일들을 로드하며, 클래스패스가 지정되어 있지 않은 경우에는 현재 위치한 디렉토리로 설정된다. 클래스패스는 프로그램 실행 시에 커맨드라인에서 -cp 혹은 -classpath 옵션을 사용해 변경이 가능하다.

또한, 필요에 따라 기존의 클래스로더를 상속 받아 확장해서 새로운 클래스 로더를 생성할 수 있다.

2) Runtime Data Area

프로그램을 수행하기 위해 OS로부터 메모리를 할당받은 공간이다. Runtime Data Area는 다음과 같이 구성되어 있다.

  • Method Area(= Class Area, Static Area) : 클래스 멤버 변수, 메소드 정보, Type(Class or Interface)정보, Constant Pool, static, final 변수 등이 생성된다. 상수 풀은 모든 Symbolic Reference를 포함한다. 다른 스레드에서도 활용할 수 있는 공유자원이다.
  • Heap Area : new 연산자를 통해 생성된 오브젝트와 배열이 저장되는 곳이다. Method Area에 저장된 클래스 정보를 복사하여 Heap 영역에서 메모리를 할당해 사용한다. 여러 스레드에서 공유 가능한 영역이며, Garbage Collection의 대상이 되는 영역이다.
  • Stack Area : 지역 변수, 파라미터 등이 생성되는 영역, 동적으로 객체를 생성하면 실제 객체는 Heap에 할당되고 해당 레퍼런스는 Stack에 저장된다. Stack은 Thread별로 독자적으로 가진다.
  • PC Register : Thread가 시작될 때 생성되는 공간으로, Thread 마다 하나씩 존재한다. Thread가 어떤 부분을 어떤 명령으로 실행할 지에 대한 기록을 하는 공간이다. 현재 Thread가 실행되는 부분의 주소와 명령을 저장하고 있다.(CPU의 Register와 다름)
  • Native Method Stack : 자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역이다. 일반적인 메소드를 실행하는 경우 JVM Language Stack에 저장되지만, Native Method Stack은 네이티브 라이브러리에 따라 네이티브 코드 명령을 보관한다.

3) Execution Engine

메모리에 적재된 클래스들을 기계어(바이너리 코드)로 변경해 명령어 단위로 실행하는 역할을 한다. 코드를 변경하는 방식에는 인터프리터 방식과 JIT 방식이 있다.

JVM 아키텍처 요약

  • JVM은 Class Loader System을 통해 Class 파일들을 JVM으로 로딩
  • 로딩된 Class 파일은 Execution Engine을 통해 해석
  • 이렇게 해석된 프로그램은 Runtime Data Areas에 배치되어 실질적인 수행이 이루어짐
  • 이 과정에서 필요에 따라 Thread Synchronization과 Grabage Collection(더이상 사용하지 않는 오브젝트나 메모리를 정리함)을 수행

6. JDK와 JRE의 차이

JRE(Java Runtime Environment)

JRE는 컴파일된 자바 프로그램을 실행시킬 수 있는 자바 환경으로, JVM이 자바 프로그램을 동작시킬 때 필요한 라이브러리 파일들과 기타 파일들을 가지고 있다. JRE는 JVM의 실행환경을 구현한 것이다.

자바 프로그램을 실행시키기 위해서 반드시 필요하며, 자바 프로그래밍 도구(JDK)는 포함되어 있지 않기 때문에 프로그래밍은 불가능하다. (읽기 가능, 쓰기 불가)

이미지 출처:  https://wikidocs.net/257

JDK(Java Development Kit)

JDK는 JRE를 포함하여, 자바 프로그램 개발을 위해 필요한 컴파일러 및 도구(javac, java등)들을 포함한 것이다.

이미지 출처:  https://wikidocs.net/257

참고 URL

'개발 > 자바' 카테고리의 다른 글

Week-02-Variables  (0) 2021.04.17