개발/Java

자바 가상 기계 (JVM, Java Virtual Machine)

냐냐_ 2021. 3. 18. 12:17

출처 : 이미지 내 표기

 

JVM 개념 설명에 가장 많이 돌아다니는 이미지로 포스트를 시작 :-)

 

 

 

 

 

이전 포스팅에서, 프로그래밍 언어는 완전한 기계어(0101011110111)가 아니라

인간 언어와 기계어 사이에 있는 통역사 같은 언어라고 했었다.

그래서 운영체제는 프로그래밍 언어를 직접 해석하지 못한다. (쨌든 기계어가 아니니까!)

 

기계어가 아닌, 이 '프로그래밍 언어'를 해석하기 위해서는 가상의 운영체제가 필요하다.

자바에게는 그것이 바로 자바 가상 기계인 JVM이다.

 

자바를 어느 대기업 회장님이라고 치자.

회장님은 전 세계 어딜 가도 두렵지 않다. 전담 통역사가 있으니까.

중국어, 스페인어, 일본어, 다 회장님이 할 필요 없다. 통역해 주니까.

 

대신 통역사는 중국어 통역사, 스페인어 통역사가 달라야 할 거다.

그래서 자바는 운영체제에 종속적이지 않지만,

JVM은 운영체제에 종속적이다. 각 운영체제에 맞게 세팅해야 한다!

 

 

 

 

 

자바 프로그램의 실행 단계

가장 쉽게 생각하면,

 

"내 코드는 내가 짤 수 있는 거 보면 기계보단 사람에게 쉬운 언어구나.

 그래서 기계가 이해하기 좋게 바꿔줘야 하나 보다.

 근데 다른 언어는 그게 한 단계인데,

 자바는 어떤 운영체제에서도 쓸 수 있는 공용어가 필요해서 두 단계래.

 어쨌든 두 단계를 거쳐 기계어로 바뀌어 실행이 되는구나."

 

라고 생각하면 됨!

 

출처 : https://techvidvan.com/tutorials/java-virtual-machine/

 

1. 유저는 확장자가 .java 인 소스 파일을 작성한다.

2. 이 소스 파일은 컴파일러 javac.exe를 통해 컴파일되어,

   확장자가 .class 인 바이트 코드 파일이 된다.

   (jvm은 바이트 코드만 알아들을 줄 안다!)

3. 바이트 코드 파일은 JVM에 의해 각 운영체제에 맞는 기계어로 번역된다.

    바이트 코드는 하나지만 번역본은 여러 가지가 나올 수 있다 (중국어, 스페인어, 일본어...)

 

 

 

 

 

여기서 확인할 수 있는 한 가지.

 

Q. 자바가 C, C++보다 느리다던데요?

A. 넹! 한 번에 기계어로 바뀌는 게 아니라, 바이트 코드로 바뀌었다가 기계어로 바뀌니까요!

 

 

 

 

 

자바 런타임 메모리 구조

위에서 우리가 짠 소스 파일이 컴파일러를 거쳐

.class 확장자를 가진 바이트 코드 파일이 된다고 했다.

그 파일이 어떻게 실행되는지 조금만 더 깊게 파 보자..!

 

출처 : https://jeong-pro.tistory.com/148

 

일단 클래스 파일은 Class Loader라는 배달기사에 의해서

Runtime Data Area라는 데이터 창고*에 차곡차곡 쌓인다. (옥뮤다...?)

교재, 강의등에서는 '적재한다'고 표현한다.

- Runtime Data Area라는 창고는 여러 칸으로 나뉘어져 있다.

   메소드 영역, 힙 영역, 스택 영역 등등.

Garbage Collector라는 청소부는 데이터 창고 중 힙 영역이라는 방을 탐색하며

쓸모없는 객체를 지워준다.

어쨌든, 창고에 쌓인 클래스 파일들은 Execution Engine에 의해서

기계어로 변해 실제 실행이 된다!

 

 

 

 

 

데이터 창고의 방에 대해 조금만 더 자세히 보면,

1) 메소드 영역은 말 그대로 메소드 이름, 상수나 Static 변수 등

    계속해서 쓰여질 것들이 쌓이는 방.

2) 힙 영역은 새로운 객체나 배열이 쌓이는 방. (참조당하는 녀석들)

3) 스택 영역은 지역변수, 리턴 값, 임시 값들이 쌓이는 방이다.

1) 메소드 영역과 2) 힙 영역은 모든 쓰레드가 공유한다.

 

위 이미지 출처의 블로그에서 남겨 주신 설명은 아래와 같다.

 

클래스 Person p = new Person(); 이라는 소스를 작성했다면
Person p는 스택 영역에 생성되고 new로 생성된 Person 클래스의 인스턴스는 힙 영역에 생성된다.
그리고 스택영역에 생성된 p의 값으로 힙 영역의 주소값을 가지고 있다.
즉, 스택 영역에 생성된 p가 힙 영역에 생성된 객체를 가리키고(=참조하고) 있는 것이다.

출처: 
https://jeong-pro.tistory.com/148
 [기본기를 쌓는 정아마추어 코딩블로그]

 

한 번에 이해하려 하지 말고, 그렇구나... 하고 나중에 다시 보고, 다시 보면

볼 때마다 조금씩 더 이해된다.

구조에 대한 더 깊고 전문적인 설명은 위 이미지의 출처에 잘 나와 있다.