[STUDY HALLE] 1주차 - JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가

paulus0617·2020년 12월 21일
0

Java_Live_Study

목록 보기
1/4
post-thumbnail

목표

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

학습할 것

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

JVM

정의

JVM은 'Java Virtual Machine'의 줄임말로 직역하면 '자바를 실행하기 위한 가상 기계(컴퓨터)' 라고 할 수 있다.
JAVA로 작성된 어플리케이션은 모두 JVM에서만 실행되기 때문에 자바 어플리케이션이 실행되기 위해서는 반드시 JVM이 필요하다.

작동


위의 그림처럼 일반 어플리케이션의 코드는 OS만 거치고 HW로 전달되는데, Java어플리케이션은 JVM을 한번 더 거친다.

단점

JVM을 거친 코드는 하드웨어에 맞게 완전히 컴파일된 상태가 아니고 실행 시에 해석되기 때문에 속도가 느리다.
요즘엔 'JIT 컴파일러'와 최적화 기술이 향상되면서 속도가 빨라졌다

장점

일반 어플리케이션은 OS종속적 → 다른 OS에서 실행시키기 위해서는 어플리케이션은 해당 OS에 맞게 변경해야된다
But Java 어플리케이션은 JVM과 상호작용 → 다른 OS에서도 변경없이 사용 가능하다
Write once, run anywhere!


컴파일하는 방법

컴파일이란?

CPU가 명령을 처리할 때 모든 명령을 0 또는 1로 이해하고 실행한다. 그래서 고급언어로 작성된 소스코드를 컴퓨터가 이해할 수 있도록 기계어로 변환해야하는데 그것이 '컴파일' 과정이다.
Java에서 예를 들자면, .java 파일을 .class 파일로 변환하는 과정

How?

먼저 Java로 프로그래밍을 하기 위해서는 JDK를 설치해야한다.
설치한 JDK 폴도 안에 bin 디렉토리를 path에 추가한다.
bin 디렉토리 : Java로 프로그램을 개발하는데 필요한 실행파일들이 들어있다.
path : OS가 파일의 위치를 파악하는데 사용하는 경로

그럼, 컴파일을 위해 JDK의 bin 디렉토리에 있는 주요 실행파일들을 알아보자

  • javac.exe
    * Java 컴파일러
    * Java 소스코드를 바이트코드로 컴파일한다
    * 사용 예) javac Test.java
  • java.exe
    * Java 인터프리터
    * 컴파일러가 생성한 바이트코드를 해석하고 실행한다
    * 실행 예) java Test
  • javap.exe
    * 역어셈블러
    * 컴파일된 .class 파일을 원래의 소스로 변환한다(선언부만 저장됨)

.java 파일을 컴파일하기 위해 javac 명령어를 사용하면 .class 파일이 생성된다.


실행하는 방법

앞서 살펴본 bin디렉토리의 주요 실행파일에서 java 명령어를 사용한다.
javac로 생성된 .class 파일에 java [클래스 파일명]을 하면 java 인터프리터로 실행한다.

터미널에서 위 사진과 같이 Java 어플리케이션을 실행시켰을 때의 내부 진행순서

1. 프로그램의 실행에 필요한 .class 파일을 로드한다
2. .class 파일을 검사한다(파일형식, 악성코드)
3. 지정된 클래스(Test)에서 main(String[] args)를 호출한다
4. main메서드의 첫 줄부터 코드가 실행되고, 마지막 코드까지 모두 실행되면 프로그램을 종료하며 프로그램에서 사용했던 자원들은 모두 반환된다


바이트코드란 무엇인가

Java에서 컴파일이란 소스코드를 바이트코드로 변환하는 것을 의미한다.
따라서 바이트코드란, JVM이 이해할 수 있는 기계어라고 할 수 있다.
JVM은 바이트코드를 해당 OS의 기계어로 변환하여 OS로 전달한다.


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

JIT 컴파일러?

기존의 해석(interpret)방식이 속도가 느리다는 단점이 있었는데, 이것을 해결하기 위해 등장한 것이다.
바이트코드를 하드웨어의 기계어로 바로 변환해준다.

어떻게 동작하는가

런타임에 JVM은 클래스 파일을 로드하고 각 개별 바이트코드의 의미를 결정하며 적절한 계산을 수행한다.
JIT 컴파일러는 런타임에 바이트코드를 기계어로 컴파일하여 Java 프로그램의 성능을 향상시킨다.


JVM 구성요소


JVM은 크게

  • Class Loader
  • Execution Engine
  • Garbage Collector
  • Runtime Data Area

이렇게 4가지로 이루어져있다

Class Loader

Java에서 로딩 과정은 Class Loader가 .class 클래스 파일의 위치를 찾아 그것을 JVM 위에 올려놓는 과정을 뜻한다.
Runtime 시에 동적으로 클래스를 로드한 뒤, jar파일 내 저장된 클래스들을 JVM위에 탑재하고 사용하지 않는 클래스들은 메모리에서 삭제한다.
보통 Java로 작성된 어플리케이션은 여러 개의 클래스로 구성되어 있다. Java는 동적 로딩을 지원하기 때문에 실행 시에 모든 클래스가 로디오되지 않고 필요한 시점에 클래스를 로딩하여 사용할 수 있다는 장점이 있다.
이러한 역할을 Class Loader가 수행한다.
보다 자세한 설명

Execution Engine

실행 엔진이라고도 하며, 클래스를 실행시키는 역할이다. 클래스 로더가 JVM내의 런타임 데이터 영역에 바이트 코드를 배치시키고, 이것은 실행엔진에 의해 실행된다. 자바 바이트코드는 기계가 바로 수행할 수 있는 언어보다는 비교적 인간이 보기 편한 형태로 기술된 것이다. 그래서 실행 엔진은 이와 같은 바이트코드를 실제로 JVM내부에서 기계가 실행할 수 있는 형태로 변경한다. 이 때 두 가지 방식(Interpreter, JIT)을 사용하게 된다.

Garbage collector

자동 메모리 관리 기능이다.
Java로 작성된 프로그램이 실행되면, Garbage collector가 자동적으로 메모리를 관리해주기 때문에 프로그래머는 메로리를 따로 관리하지 않아도 된다.
자동으로 메모리를 관리한다는 것이 비효율적인 측면도 있지만 프로그래머가 보다 프로그래밍에 집중할 수 있도록 도와준다.

Runtime Data Area

Runtime Data Area는 JVM이 프로그램을 수행하기 위해 OS로부터 할당 받는 메모리 영역이다. Runtime Data Areas는 각각의 목적에 따라 5개의 영역으로 나뉘게 된다.

  • PC Registers
    PC Registers는 Thread가 생성될 때 마다 생기는 공간으로 Thread가 어떠한 명령을 실행하게 될지에 대한 부분을 기록을 한다.
    JVM은 Stacks-Base 방식으로 작동 하는데, JVM은 CPU에 직접 Instruction을 수행하지 않고, Stack에서 Operand를 뽑아내 이를 별도의 메모리 공간에 저장하는 방식을 취하는데, 이러한 메모리 공간을 PC Registers라고 한다.
  • Method Area
    프로그램 실행 중 클래스가 사용되면 JVM은 해당 클래스 파일을 읽어서 분석하여 클래스의 인스턴스 변수, 메소드 코드 등을 Method Area에 저장한다. 이 때 클래스 변수도 이 영역에 함께 생성된다.
    프로그램이 실행되면 모든 코드가 저장되어 있는 상태가 아니다. new 키워드를 통해 객체가 동적으로 생성되기 이전에는 텍스트 일 뿐이다.
  • Heap
    사용자가 관리하는 인스턴스가 생성되는 공간으로, 객체를 동적으로 생성하면 인스턴스가 Heap 영역의 메모리에 할당되어 사용되어진다.
    프로그램은 시작될 때 미리 Heap 영역을 많이 할당해 놓으며 인스턴스와 인스턴스 변수가 저장된다. 레퍼런스 변수의 경우 Heap에 인스턴스가 저장 되는것이 아니라 포인터가 저장된다.
    (Garbage Collection의 대상이 되는 영역 이다.)
  • JVM Stacks
    Thread 제어를 위해 사용되는 메모리 영역이다.
    Thread가 생성될때 마다 하나씩 생성되며 단일 Thread 당 Method가 호출될 때 메모리를 차지하게 된다.
    Method 가 호출 되면 Method와 Method 정보는 Stack에 쌓이게 되며 Method 호출이 종료 될때 Stack point에서 제거 된다. Method 정보는 해당 Method의 매개변수, 지역변수, 임시변수 그리고 어드레스(메소드 호출 한 주소)등을 저장하고 Method 종료시 메모리 공간이 사라진다.
  • Native Method Stacks
    자바 이외의 이기종 언어에서 제공되는 Method의 정보가 저장 되는 공간, JNI를 통해 표준에 가까운 방식으로 구현이 가능하다.

JDK와 JRE의 차이

JDK

  • 자바개발도구(Java Development Kit)
  • JRE + 개발에 필요한 실행파일(javac.exe 등)

JRE

  • 자바실행환경(Java Runtime Environment)
  • 자바로 작성된 응용프로그램이 실행되기 위한 최소 환경
  • JVM + 클래스라이브러리(Java API)
profile
step by step...my devlog

2개의 댓글

comment-user-thumbnail
2020년 12월 22일

아주 자세한 설명 좋네요.
이대로 책으로 내도 되겠어요^^

1개의 답글