본문 바로가기
Java

JVM

by 스르나 2021. 2. 14.

JVM

jvm(java virtual machine)은 자바를  실행하는데 필수적인 것이다. 한글로 말하면 자바 가상 기계인데, 여기서 기계라는 말때문에 좀 다르게 이해할 수 있는데 여기서 기계는 컴퓨터에서 실행되는 프로그램으로 의미하면 편하다. 그렇기 때문에 jvm은 컴퓨터에서 자바 파일을 실행하기 위한 프로그램으로 생각하면 된다.

 

JVM의 역할

JVM은 크게 2가지 역할을한다.

 

첫째, 자바 프로그램을 실행되는 기계에 관계없이 실행되도록 한다.(플랫폼 독립적)

둘째, 자바 프로그램이 실행되면서 메모리관리, 최적화등의 역할을 한다.

 

첫번째 역할을 보면 실행되는 플랫폼에 상관없이 실행되도록한다고 했는데 좀 더 풀어서 설명하면 우리가 작성한 자바 프로그램을 실행파일로 만든다음 이것을 배포하는 경우를 생각해보자. 실행되는 컴퓨터는 모두 다를 것이다. 어떤 컴퓨터는 OS가 윈도우일 수도있고, MAC일 수도있다. 또한 64비트 컴퓨터일 수도 있고, 32비트 컴퓨터일 수도 있다. JVM은 이런 환경을 무시하고 개발할 수 있게 해준다. (JAVA의 모토는 Write Once, Run anywhere 한번 작성하고 어디서든 실행한다. 이다.) 참고로 플랫폼은 OS+CPU라고 생각하면 된다. 예를 들어 linux OS를 사용중이고 AMD CPU를 사용중인 컴퓨터와 window OS와 intel CPU를 사용중인 컴퓨터는 서로다른 플랫폼인것이다. 이렇게 서로 다르다면 OS에서 사용하는 시스템콜이 다르고 CPU의 아키텍처가 다르기 때문에 C/C++은 동작하지 않는다.

 

두번째 역할은 최적화의 역할이다. 애플리케이션은 실행이 되기위해 컴퓨터의 메모리를 할당 받아야한다. 그리고 이 할당 받은 메모리는 한정적이기 때문에 이 메모리를 최대한 효율적으로 사용하는것이 중요하다. 이런 관리가 개발에서 아주 핵심적인 언어가 C,C++이다 이 2언어는 개발자가 직접 메모리를 관리해야한다. 사람이 직접 코드로 메모리를 관리하기 때문에 종종 메모리 누수가 생긴다. 하지만 자바는 이런 메모리 관리를  JVM이 해준다.

 

Java의 실행 과정

우선 JVM이 구체적으로 어떤 작업들을 하는지 알기 위해서는 java의 실행과정을 알아야한다.

 

먼저 우리가 작성한 .java파일이 자바 컴파일러(javac)에 의해 .class파일로 변환된다. ,class파일은 바이트 코드로 작성되어있다. 그다음 이 .class 파일을 JVM의 클래스 로더가 JVM으로 가져온다. 가져온 .class파일을 실행엔진이 해석을 한다. 이렇게 해석이 된것들이 실행할때 할당받은 메모리에 놓여진다.

 

다시한번 순서대로 정리를 해보면 아래와 같다

 

1. java파일을 자바 컴파일러가 .class파일로 번역

2. .class파일을 클래스 로더가 JVM으로 가지고온다

3. 가지고온 .class파일(byte 코드)을 실행엔진이 번역해서 binary 코드로 만든다.

4. 변역이 된뒤에 할당받은 메모리에 놓여진다.

 

 

JVM 구조

출처: https://dailyheumsi.tistory.com/196

 

JVM의 구조를 하나하나 천천히 보자

 

1. 클래스로더

 

1-1 로딩

-> .class파일을 JVM으로 가져온다

 

1-2 링크

-> 한 코드에 관련된 다른 코드들을 가져온다. 예를들어 main.java 파일에서 ArrayList를 import했다면 ArrayList파일을 연결(link)한다.

 

1-1 초기화

-> static으로 선언된것을 먼저 메모리에 올린다.(초기화)

 

2. 메모리

 

2-1 스택

-> 실행되면서 일시적으로 생성이 되었다가 소멸하는 데이터들이 저장되는 공간이다. 예를 들면 메소드안에서 선언한 변수, 매개변수등을 의미한다. Thread 마다 하나씩 가지고 있다

 

2-2 PC Register

-> Thread가 생성될때마다 생성되는 것으로 Thread마다 하나씩 가지고 있는 영역이다. 현재의 Thread에 대한 정보가 들어있다. Thread는 메소드를 실행하고 있는 상태인데 이 Thread가 어떤 메소드의 몇번째 줄을 실행하고 있는지에 대한 정보가 들어있다.

 

2-3 네이티브 메소드 스택

-> 네이티브 메소드가 들어있는 영역(네이티브 메소드란 자바가 다른 언어(C/C++)로 만들어진 언어와 상호작용할 때 호출하는 메소드를 의미한다. 대표저으로 Thread.currentThread메소드가 있다.) 모든 Thread가 공유 한다.

 

2-4 힙

-> 자바에서 동적으로 생성된 것들이 들어가는 영역이다. 간단하게 말하면 실행도중 new 키워드로 만든 것들(인스턴스)이 들어가는 영역이다. 모든 Thread가 공유 한다.

 

2-5 메소드(클래스 영역, 스태틱 영역이라고도 한다.)

-> 클래스 로더가 클래스를 가져오면 클래스 정보를 파싱하여 저장하는 영역(변수, 메소드, 정적 데이터 등등 클래스에 대한 정보가 들어 있다.)

 

3. 실행 엔진

 

3-1 인터프리터

-> 자바 바이트코드를 한줄씩 실행한다. 한줄씩 실행하기 때문에 느리다는 단점이 있다.

 

3-2 JIT

-> 인터프리터의 단점을 보완하기 위해 만들어진것으로 인터프리터 방식으로 실행을 하다 적절한 시점에 바이트코드 전체를 해석하여 네이티브 코드로 보관을 하여 더 이상 인터프리팅을 하지 않는다.

 

3-3 GC (Garbage Collecter)

실행도중 더 이상 참조되지 않는 메모리들을 메모리에서 해제하는 역할을 한다.

'Java' 카테고리의 다른 글

Collection Framework 정리표  (0) 2021.02.25
자바 synchronized 이해  (0) 2021.02.24
Iterator,Iterable  (0) 2021.02.13
Thread-3  (0) 2021.02.12
Thread-2  (0) 2021.02.11