본문 바로가기
스터디/whiteship - live-study

[백기선님 라이브 스터디] 1주차 - JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가

by 똧이 2022. 3. 29.
반응형

목차

JVM이란 무엇인가 & JVM 구성 요소

컴파일 하는 방법 & 실행하는 방법

바이트코드란 무엇인가

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

JDK와 JRE의 차이

 

 

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


JVM이란 무엇인가 & JVM 구성 요소

자바 실행 단계

 

JVM(Java Virtual Machine)

  • 자바를 실행하기 위한 가상머신: 자바로 작성된 애플리케이션은 모두 JVM에서만 실행됨(자바 애플리케이션 실행 시 필수)
  • 운영체제 위에서 동작하는 프로세스로 자바 코드를 컴파일 해서 얻은 바이트 코드를 해당 운영체제가 이해할 수 있는 기계어로 바꿔실행 시켜주는 역할
  • GC(Garbage Collection)을 이용하여 자동으로 메모리 관리
    • Garbage Collection
      • 메모리 힙(Heap)
        • 프로그램이 실행되면 아래 그림과 같이 4개의 메모리 영역을 가지게 된다.
        • 이중 Heap 영역은 사용자가 동적할당을 할 경우 메모리에 저장된다.
        • C언어에서는 malloc, java에서는 new 키워드로 Heap 영역에 메모리를 할당할 수 있다.
        • Heap 메모리의 해제는 C에서는 free 함수로 해제하며, java에서는 JVM에서 가비지 컬렉터가 지우는 시점에 해제
    • 자동으로 Heap 영역의 쓰지 않는 메모리를 회수
- 일반 애플리케이션 코드: OS만 거치고 하드웨어로 전달

- Java 애플리케이션 코드: JVM을 거치고 OS를 거친 후 하드웨어로 전달, 하드웨어에 맞게 완전히 컴파일된 상태 X 실행 시에 해석되기 때문에 속도가 느림(요즘에는 바이트코드를 하드웨어의 기계어로 바로 번역해주는 JIT 컴파일러 등이 있어서 이 문제는 많이 해결됨)
  • 자바가 운영체제 종류에 영향을 받지 않고 실행 가능하도록 함 → Java 애플리케이션은 JVM하고만 상호작용을 하기 때문에 OS와 하드웨어에 독립적이라 OS의 영향을 받지 않음

 

 


 

JVM 구성 요소

1. 클래스 로더 시스템(Class Loader) → 실행에 필요한 준비 과정

  • 자바 바이트 코드 파일인 .class 파일을 읽어 연결한 뒤 메모리에 저장하는 역할을 수행
  • 내부적으로는 로딩, 링크, 초기화의 단계가 존재
  • 클래스 로더 시스템 초기화 단계에서 전역 변수를 메모리에 할당하기 때문에 필요 이상으로 전역 변수를 남용할 경우 메모리 이슈를 겪을 수 있음
  • 엄밀히 말하자면 JDK가 아닌 JRE의 구성요소

2. 실행 엔진(Execution Engine) → 인터프리터를 사용하여 바이트 코드를 번역하여 실행

  • 클래스 로더를 통해 JVM으로 로딩된 자바 바이트 코드를 명령어 단위로 읽어서 실행
  • 내부적으로는 인터프리터, JIT 컴파일러 존재
    • 인터프리터(Interpreter)
      • 자바 바이트 코드를 한 줄씩 번역하고 실행하는 방식
      • 컴파일된 .class의 바이트 코드를 실행하는 역할
    • JIT(Just In Time) 컴파일러
      • Interpreter 방식의 단점을 보완하기 위해 도입된 컴파일러
      • 이미 한번 읽어서 Native Code로 변환한 소스코드는 캐싱을 통해 저장해둬서 다시 번역하지 않기 때문에 실행 속도를 높일 수 있음
      • 자세한 내용은 후술

3. 메모리(Runtime Data Area)

  • JVM의 메모리 영역
  • 자바 애플리케이션을 실행할 때 데이터를 적재하는 영역
  • 메모리(Runtime Data Area) 구성
    1. Method Area (Class Area)
      • 모든 쓰레드가 공유하는 영역으로 JVM이 시작될 때 생성
      • 클래스와 인터페이스의 상수, 메서드와 필드 정보, static, final 변수, 타입 정보 등을 보관
    2. Heap Area
      • 동적으로 생성된 오브젝트와 배열이 저장되는 영역으로, Garbage Collection에 의해 관리됨
    3. Stack Area
      • 메서드가 호출 되면 메서드 안에서 사용하는 값들과 매개 변수, 지역 변수, 리턴 값 등을 저장한 뒤, 메서드가 종료될 때 함께 삭제되는 데이터들이 임시적으로 저장되는 영역
      • 메서드가 호출되는 순서대로 쌓임
    4. PC Register
      • 현재 어떤 명령어가 실행되어야 하는지에 대해 저장하는 레지스터
      • 현재 수행 중인 JVM 명령의 주소를 갖고 있음
    5. Native Method Stack
      • 자바 이외의 언어로 작성된 Native Code를 위한 영역

4. 가비지 컬렉터(Garbage Collector)

  • Heap 영역의 메모리를 자동으로 관리
  • 프로그램이 실행되면서 특정 데이터를 저장할 때 주로 메모리를 사용 → 다양한 로직이 순차적으로 실행되다 보면 한정돼있는 메모리는 여러 데이터로 점령될 것
    • 더 이상 참조되지 않는 데이터를 정리하는 역할을 수행

 

 

 


 

컴파일 하는 방법 & 실행하는 방법

컴파일

  • 고급언어로 작성된 소스코드를 컴퓨터가 이해할 수 있도록 기계어(native code)로 변환하는 과정
  • 자바 컴파일러는 자바 개발 키트(JDK)에 포함되어 있기 때문에 작성된 코드를 컴파일해 바이트코드를 생성하기 위해선 우선 JDK가 필요
    • javac.exe는 JDK, java.exe는 JRE에 포함되어 있기에 JDK과 JRE를 설치해야 하지만 과거와 다르게 요즘은 JDK에 JRE가 포함된 형태로 배포되고 있기에 JDK만 설치해도 무관
  • .java 파일을 .class 파일로 변환하는 과정
  • 컴파일을 위해선 컴파일 작업을 수행할 java compiler가 필요 → java comiler는 jdk를 설치하면 bin 폴더안에 javac라는 이름으로 설치됨
    • javac.exe: 자바 소스코드를 컴파일 할때 사용하는 프로그램
    • java.exe: 컴파일된 바이트코드를 실행할 때 사용

 

컴파일 방법

  • class 파일 만들기
    • $ javac 파일명.java
    • javac.exe 사용하여 .java 파일 컴파일
    • 컴파일이 정상적으로 완료되면 해당 경로에 소스파일명 .class 생성
  • 파일 실행
    • $ java 파일명
    • java.exe 파일을 사용하여 바이트코드로 컴파일된 .class 실행
    • 실행시에는 소스 파일명의 확장자는 붙이지 않음

 

 


바이트코드(.class)란 무엇인가

  • JVM이 사용자가 작성한 .java 소스 파일을 운영체제에 실행가능한 명령어 집합 파일로 컴파일하는 과정 중에 필요한 코드
  • 1차적으로 .java 소스 코드파일을 사용자가 작성하면, JVM이 이를 바이트코드로 컴파일하여 .class 파일로 만든다.
  • 2차적으로 운영체제에 작용하는 기계어(native code)로 한번 더 컴파일되어 컴퓨터에 JAVA 프로그램이 실행되는 것

자바 바이트 코드

  • JVM이 이해할 수 있는 언어로 변환된 자바 소스코드를 의미
  • 자바 컴파일러에 의해 변환되는 코드의 명령어의 크기가 1byte라서 자바 바이트 코드라고 불림
  • 자바 바이트 코드는 자바 가상 머신만 설치되어 있다면 어느 운영체제에서도 실행 가능

 

 


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

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

  • Interpreter 방식의 단점을 보완하기 위해 도입
  • 프로그램을 실제 실행하는 시점에 기계어(native code)로 번역하는 컴파일 기법
  • 이미 한번 읽어서 Native Code로 변환한 소스코드는 캐싱을 통해 저장해둬서 다시 번역하지 않기 때문에 실행 속도를 높일 수 있음

 


JDK와 JRE의 차이

JDK(Java Runtime Environment)

  • 자바 개발 도구로 JRE를 포함
  • 자바의 모든 기능을 포함한 SDK(개발을 위한 패키지)
    • 소프트웨어 개발 키트 (Software development kit, SDK): 일반적으로 소프트웨어 기술자가 사용하여 특정한 소프트웨어 꾸러미, 소프트웨어 프레임워크, 하드웨어 플랫폼, 컴퓨터 시스템, 게임기, 운영 체제 등을 위한 응용 프로그램 등을 만들 수 있게 해주는 개발 도구의 집합

JRE(Java Runtime Environment)

  • 자바를 실행하기 위한 환경
  • JVM, Java 클래스 라이브러리, java명령 및 기타 인프라를 포함하여 컴파일 된 JAVA프로그램을 실행하는데 필요한 모든 것을 포함한 패키지

 


궁금한 점

가끔 블로그마다 JVM 구조 중 실행 엔진에 GC가 포함되어 있다고 나와있는 경우가 있는데, GC는 JVM 구조 중 하나로 따로 존재하는데 왜 실행 엔진 안에 GC가 포함되어 있다고 하는지?

 

답을 모르겠다 ㅜㅜ

 

 

바이트 코드를 컴파일 방식으로 처리하지 않고 인터프리터 방식으로 처리하는 이유?

  • 자바: WORA(Write Once Run Anywhere) 의 특징, 플랫폼에 독립적
  • JVM: 플랫폼(OS)에 종속적(자바로 작성된 프로그램을 특정 OS 에 맞게 변경을 해줘야 하기 때문)

→ 인터프리터 방식(class 파일을 해당 OS에 맞게 interpreter가 번역)을 사용하면 플랫폼에 구애받지 않을 수 있게 된다!

 

[ 참고 ]

  • 자바는 크로스 플랫폼(멀티 플랫폼) 언어임
    • 크로스 플랫폼(멀티 플랫폼): 다양한 플랫폼에서 사용 가능
    • Java 컴파일러는 소스코드를 컴파일해서 "바이트 코드(Byte Code)"를 생성 → 그 바이트 코드를 자신의 운영체제에 맞게 설치된 JVM 위에서 실행시키기만 하면 됨
  • 컴파일러
    • 장점: 목적프로그램을 실행할때는 컴파일을 하지 않아 속도가 월등히 빠름
    • 단점: 컴파일러는 한꺼번에 컴파일을 하기 때문에 컴파일 시간은 오래걸림
  • 인터프리터
    • 장점: 라인별로 컴파일을 하기 때문에 라인을 컴파일 하는 시간이 짧음, 플랫폼에 종속적이지 않음
    • 단점: 프로그램을 실행하는 동안 컴파일 작업도 같이 하기 때문에 프로그램 자체의 속도는 느림

 

 


출처

https://jaeseongdev.github.io/development/2021/03/08/JAVA는_인터프리터_방식과_컴파일_방식이_혼합된_언어이다/

https://jooona.tistory.com/157

https://jooona.tistory.com/158

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

https://velog.io/@jaden_94/1주차-항해일지

https://github.com/Chohongjae/javaStudy/blob/main/live-study/week1.md

https://sowhat4.tistory.com/61

https://gblee1987.tistory.com/173

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

https://aroundck.tistory.com/1949

https://ljhh.tistory.com/12

https://blog.cordelia273.space/16

https://techvu.dev/113

https://velog.io/@huttels/2020-04-19

 

728x90

댓글