본문 바로가기

공부/JAVA

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

반응형

백기선님 자바 기초 스터디 follow up

깃허브 :https://github.com/whiteship/live-study

 

 

JVM 구조

JVM은 자바 가상머신으로 자바 바이트코드를 실행 할 수 있는 주체로 JVM 덕분에 CPU나 운영체제(플랫폼)과 독릭접으로 동작 가능하다JVM은 크게 Class Loader,GC, Runtime Data Area, Excute engine 세가지로 나

velog.io

목차

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

 

1. JVM이란 무엇인가

 

JVM은 Java Virtual Machine의 줄임말로, Java와 OS 사이에 존재하는 가상머신이다.

자바로 작성된 애플리케이션은 모두 JVM에서만 실행되기 때문에, 자바 애플리케이션이 실행되기 위해서는 반드시 JVM이 필요하다. 일반 애플리케이션의 코드는 OS만 거치고 하드웨어로 전달되는데 비해 Java애플리케이션은 JVM을 한 번 더 거치기 때문에, 하드웨어에 맞게 완전히 컴파일된 상태가 아니고 실행 시에 해석된다.

 

Java Compiler는 .java파일을 .class라는 'Java byte code'로 변환

 - byte 코드는 기계거악 아니기 때문에 os에서 바로 실행이 안된다.

 

JVM은 OS가 ByteCode를 이애할 수 있도록 해석해 주는 역할을 한다.

 - JVM은 c언어 같은 네이티브 언어에 비해 속도가 느리지만, JIT(Just In Time)컴파일러 구현을 통해 이 점을 극복한다.

 

Byte코드는 JVM 위에서 OS에 상관없이 실행된다.

 - JVM은 OS에 독립적이지만 의존적이다.

 

gc를 이용하여 자동으로 메모리 관리를 해준다.

 

 

JVM의 특징은 다음과 같다.

  • 스택 기반의 가상 머신: 대표적인 컴퓨터 아키텍처인 인텔 x86 아키텍처나 ARM 아키텍처와 같은 하드웨어가 레지스터 기반으로 동작하는 데 비해 JVM은 스택 기반으로 동작한다.
  • 심볼릭 레퍼런스: 기본 자료형(primitive data type)을 제외한 모든 타입(클래스와 인터페이스)을 명시적인 메모리 주소 기반의 레퍼런스가 아니라 심볼릭 레퍼런스를 통해 참조한다.
  • 가비지 컬렉션(garbage collection): 클래스 인스턴스는 사용자 코드에 의해 명시적으로 생성되고 가비지 컬렉션에 의해 자동으로 파괴된다.
  • 기본 자료형을 명확하게 정의하여 플랫폼 독립성 보장: C/C++ 등의 전통적인 언어는 플랫폼에 따라 int 형의 크기가 변한다. JVM은 기본 자료형을 명확하게 정의하여 호환성을 유지하고 플랫폼 독립성을 보장한다.
  • 네트워크 바이트 오더(network byte order): 자바 클래스 파일은 네트워크 바이트 오더를 사용한다. 인텔 x86 아키텍처가 사용하는 리틀 엔디안이나, RISC 계열 아키텍처가 주로 사용하는 빅 엔디안 사이에서 플랫폼 독립성을 유지하려면 고정된 바이트 오더를 유지해야 하므로 네트워크 전송 시에 사용하는 바이트 오더인 네트워크 바이트 오더를 사용한다. 네트워크 바이트 오더는 빅 엔디안이다.

2. 컴파일하는 방법

컴파일 : 사용자가 작성한 코드를 컴퓨터가 이해할 수 있는 기계어로 변환하는 과정. 목적파일이 생성된다. (자바의 경우 *.class)

 

인터프리터: 한 문장씩 읽고 바로바로 기계어로 바꾸어 실행.

 

Java에서 컴파일은 기존의 컴파일 과정과는 조금 다르게 진행됩니다. 컴파일 언어의 컴파일러들은 코드를 기계어로 변환시키는데 반해 Java의 컴파일러인 javac.exe는 JVM이 이해할 수 있게 중간 단계의 언어인 바이트 코드로 변환시켜 줘서 프로그램을 실행하게되면 JVM이 이 바이트 코드를 기계어로 변환시켜 실행

 

javac.exe 

- 자바 컴파일러 : 자바 소스코드를 바이트코드로 컴파일

java.exe

- 자바 인터프리터 : 컴파일러로 생성된 바이트코드를 해석하고 실행

javap.exe

- 역 어셈블러 : 컴파일된 클래스파일을 원래의 소스로 변환

jar.exe

- 압축 : 자바프로젝트를 실행시키기 위한 파일들을 압축

javadoc.exe

- 문서화 : 자바파일에 있는 주석들을 문서화

 

자바 소스 코드 파일(.java) -> javac 컴파일러 -> JVM 바이트코드(.class)

- javac 파일명

 

3. 실행하는 방법

 

java.exe 파일을 사용하여 바이트코드로 컴파일된 .class 실행 or IDE에서 jdk를 등록후 실행하면 class확장자의 바이트코드를 JVM이 읽어서 실행하게 됩니다.

-java 소스파일명

 

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

특정 하드웨어가 아닌 가상 컴퓨터에서 돌아가는 실행 프로그램을 위한 이진 표현법. 자바 컴파일러에 의해 변환되는 코드의 명령어 크기가 1바이트라서 자바 바이트 코드라고 불리고 있으며 확장자는 .class. 자바 가상 머신상에서 실행하기 위한 코드이기 때문에 운영체제에 상관없이 JVM만 설치되어 있다면 어떤 운영체제에서도 동일하게 동작.

 

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

 

 Java에서 기존 클래스 파일인 바이트코드를 실행하는 방법은 interpreter 방식이다. interpreter는 명령어를 하나씩 해석하여 처리하기 때문에 명령어를 하나씩 실행하는 속도는 빠를지 모르지만 전체적인 코드를 생각하면 실행 속도가 느린 것을 알 수 있다. 이를 해결하기 위해 JIT 컴파일러가 등장하였다.

 

JIT(just in time) 컴파일러

프로그램을 실제 실행하는 시점(런타임 시점)에 기계어로 번역하는 컴파일 기법을 활용한 컴파일러

 

 JIT 컴파일러는 자주 사용하는 코드를 캐싱하고 이후에 같은 코드가 나오면 캐싱된 것을 가져다 쓴다. 매번 기계어로 번역하는 interpreter 방식보다 빠르게 기계어로 번역할 수 있다.

 

 JIT 컴파일러는 런타입 시에 동작한다. interpreter와 함께 Thread로 동시에 동작한다.

 

 단점은 초기 구동할 때 런타임 단계에서 컴파일하는데 시간과 메모리를 소모한다. 정적 컴파일된 프로그램에 비해 실행속도가 느리다.

 

6. JVM 구성 요소

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

 

* class loader

자바 컴파일러가 .java 파일을 컴파일하면 .class 파일(바이트코드)가 생성된다. 이렇게 생성된 클래스 파일들을 엮어 Runtme Data Area 형태로 메모리에 적재하는 역할을 한다.

 

* Execution Engine

메모리에 적재된 클래스들을 기계어로 변경해 명령어 단위로 실행하는 역할을 한다.

명령어를 하나하나 실행하는 인터프리터 방식과 실행 시점에 자주 쓸만한 코드들을 기계어로 변환시켜놓고 저장해서 사용하는 JIT 방식이 있다.

 

*Garbage Collector

https://velog.io/@litien/%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%ED%84%B0GC 참고

Heap 메모리 영역에 생성된 객체들중에 Reachability를 잃은 객체를 탐색 후 제거하는 역할을 한다.

 

'정리되지 않은 메모리': 프로그래밍 언어에서는 Danling Object, 자바에서는 Garbage라고 부른다.

 

가비지는 메모리가 부족할 때 이런 가비지들을 메모리에서 해제 시켜 다른 용도로 사용 할 수 있게 해주는 프로그램을 말한다.

 

Stop the world

gc 실행을 위해 jvm이 애플리케이션 실행을 멈추는것. gc가 실행될 때는, gc를 실행하는 쓰레드를 제외한 모든 쓰레드들이 작업을 멈춘다.

gc 튜닝: stop-the-world 시간을 줄이는 것

 

gc 과정 (mark and sweep)

스택의 모든 변수 또는 reachable 객체를 스캔하면서 각각 어떤 객체를 참조하고 있는지 찾는 과정 - Mark

이 과정에서 Stop-the-world 발생

이후 Mark 되어있지 않은 객체들을 힙에서 제거하는 과정이 Sweep

 

Minor GC와 Major GC

JVM의 Heap은 Young, Old, Perm 세 영역으로 나눔.

Young 영역에서 발생한 GC를 Minor GC, 나머지 두 영역에서 발생한 GC를 Major GC(Full GC)라고 한다.

 

  • Young 영역 : 새롭게 생성한 객체가 위치, 대부분의 객체가 금방 unreachable 상태가 되기 때문에 많은 객체가 Young 영역에 생성되었다가 사라진다.
  • Old 영역 : Young 영역에서 reachable 상태를 유지해 살아남은 객체가 여기로 복사된다. 대부분 Young 영역보다 크게 할당하며, 크기가 큰 만큼 Young 영역보다 GC는 적게 발생한다.
  • Perm 영역 : Method Area라고도 한다. 클래스와 메소드 정보와 같이 자바 언어 레벨에서는 거의 사용되지 않는 영역이다.

Reachability

어떤 객체에 유효한 참조가 있으면 'reachable' 없으면 'unreachable' unreachable은 가비지로 간주

 

 *Runtime Data Area

-Method Area

클래스 멤버 변수, 메소드 정보, Type(Class or interface)정보, Constant Pool, static, final 변수 등이 생성된다. 상수 풀은 모든 Symbolic Reference를 포함하고 있다.

 

-Heap Area

동적으로 생성된 오브젝트와 배열이 저장되는 곳으로, Garbagte Collection의 대상이 되는 영역이다.

 

-Stack Area

지역 변수, 파라미터 등이 생성되는 영역, 동적으로 객체를 생성하면 실제 객체는 Heap에 할당되고 해당 레퍼런스만 Stack에 저장된다. Stack은 스레드별로 독자적으로 가진다.

 -> Heap에 있는 오브젝트가 Stack에서 참조할 수 없는 경우 GC의 대상이 된다.

 

-PC Register

현재 쓰레드가 실행되는 부분의 주소와 명령을 저장하고 있다.(CPU의 PC Register와 다르다.)

 

-Native Method Stack

자바외 언어로 작성된 네이티브 코드를 위한 메모리 영역

 

 

 

7. JDK와 JRE 차이

 

JDK : 자바 프로그래밍 시 필요한 컴파일러 등 포함 - Java Development Kit

  • JDK는 개발을 위해 필요한 도구(javac, java 등)들을 포함한다.
  • JDK를 설치하면 JRE도 같이 설치가 된다.
  • 즉 JDK = JRE + @라고 생각하면 된다.

JRE : 컴파일된 자바 프로그램을  실행시킬 수 있는 자바 환경 - Java Runtime Enviroment

  • JRE는 JVM이 자바 프로그램을 동작시킬 때 필요한 라이브러리 파일들과 기타 파일들을 가지고 있다.
  • JRE는 JVM의 실행환경을 구현했다고 할 수 있다.
  • 자바 프로그램을 실행시키기 위해선 JRE를 반드시 설치해야 한다.
  • 하지만 자바 프로그래밍 도구는 포함되어있지 않기 때문에 자바 프로그래밍을 하기 위해선 JDK가 필요하다.

java source code -> (JDK) -> bytecode -> (JRE) -> 프로그램 실행

 

8. 추가

 

컴파일타임 vs 런타임

타임 설명
컴파일타임 개발자가 소스코드를 작성하고 컴파일을 통해 실행 가능한 프로그램이 되는 과정을 의미한다.
런타임 컴파일 과정을 마친 애플리케이션이 사용자에 의해서 실행되는 시점을 의미한다.

[참고] bash에서 javac를 실행하는 부분이 컴파일타임이고, 인텔리제이나 이클립스같은 idea에서는 소스코드를 작성하는 중에도 상시로 컴파일이 되고 있다.

 

참고 사이트

https://hyeonic.tistory.com/8

https://github.com/kksb0831/Practice_project/blob/master/Java_Study_01.md

 

GitHub - kksb0831/Practice_project

Contribute to kksb0831/Practice_project development by creating an account on GitHub.

github.com

 

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

whiteship/live-study 온라인 스터디. Contribute to whiteship/live-study development by creating an account on GitHub. github.com 목표 자바 소스파일(.java)을 JVM으로 실행하는 과정 이해하기. 학습할 것..

hyeonic.tistory.com

https://wonyong-jang.github.io/java/2020/11/08/Java-JVM.html

 

[Java] JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가 - SW Developer

1)Java Virtual Machine 은 자바를 실행하기 위한 자바 가상머신이다. 자바와 운영체제 사이에서 중계자 역할을 하며, 자바가 운영체제 종류에 영향을 받지 않고 실행 가능하도록 한다. 2) 운영체제 위

wonyong-jang.github.io

https://d2.naver.com/helloworld/1230

https://shinysblog.tistory.com/30

https://velog.io/@ggob_2/java-study-1

https://velog.io/@litien/JVM-%EA%B5%AC%EC%A1%B0

 

JVM 구조

JVM은 자바 가상머신으로 자바 바이트코드를 실행 할 수 있는 주체로 JVM 덕분에 CPU나 운영체제(플랫폼)과 독릭접으로 동작 가능하다JVM은 크게 Class Loader,GC, Runtime Data Area, Excute engine 세가지로 나

velog.io

https://velog.io/@litien/JVM-%EA%B5%AC%EC%A1%B0

반응형

'공부 > JAVA' 카테고리의 다른 글

자바 데이터 타입, 변수 그리고 배열  (0) 2021.07.31