티스토리 뷰

자바 언어는 JVM(Java Virtual Machine)을 사용해 플랫폼에 독립적인 개발을 가능하게끔 해준다

(Write Once, Run Anywhere)

JVM - JRE(Java Runtime Enviroment) - JDK(Java Development Kit) 순서로 포함되어 있는 구조를 갖게된다.

JVM이 그만큼 핵심이라는것.

 

 

그럼 자바 코드는 어떤 식으로 실행되는 것일까?

# 바이트 코드란?

- 고급 언어로 작성된 코드를 JVM이 이해할 수 있는 언어로 변환된 코드

- 명령어 크기가 1바이트라서 바이트 코드라고 불린다.

 

# 왜 바이트 코드가 필요할까? 고급 언어에서 기계어로 바로 바꾸면 안될까?

-> 바이트코드는 가상머신(JVM)에서 돌아가는 프로그램을 위한 언어 표기법이다. 

-> 같은 print 명령어라도 윈도우 OS에서 쓰이는 기계어와 맥 OS에서 쓰이는 기계어는 다르다. 그렇기 때문에 JVM이 공통적으로 이해할 수 있는 정도로 1차 번역을 거치고, OS에 따른 번역은 각 OS에 맞는 JVM이 처리하도록 하는 것.

 

* 컴파일 시에 주석은 번역하지 않는다

 

 

# JVM의 역할

1. 운영체제에 구애받지 않고 자바 프로그램을 실행할 수 있게 해준다.

2. 메모리 관리를 수행한다 (GC)

 

# JVM의 구조

1. Class Loader: JAVA 바이트코드 파일을 JVM 내부로 로드한다.

 

2. Execution Engine: 바이트코드를 해석하고 실행한다(바이트 코드를 기계어로 변환)

- JVM 내의 Runtime Data Area에 배치된 바이트 코드를 명령어 단위로 읽어 실행한다.

- 인터프리터, JIT 컴파일러, GC

 

3. Runtime Data Area: 프로그램 수행을 위해 OS에게 할당받은 메모리 공간.

- Heap: 동적으로 생성된 객체(new 명령어로 생성된 객체)가 저장되는 영역. GC가 관리. 모든 스레드에 공유

- Method Area: 클래스, 인터페이스, 생성자, 메서드, 변수 정보 등 저장. 모든 스레드가 공유

- Stack: 메서드를 호출할때마다 스택 프레임을 스택에 push.

        > 메서드 내에서 사용되는 지역변수, 매개변수, 리턴값 등 저장. 각 스레드마다 존재

        > 메서드가 종료되면 프레임을 스택에서 pop.

- PC Register: 현재 수행중인 JVM 명령어 주소를 저장. 각 스레드마다 존재.

- Native Method Stack: 자바 외 다른 언어(C++ 등)의 동작을 위해 할당된 영역. 각 스레드마다 존재

 

 

클래스 로더(Class loader)

말 그대로 클래스를 로딩해주는 역할을 수행한다.

- 바이트 코드(.class)를 JVM 내부로 로딩하는 역할을 맡는다.

- 로딩은 의외로 컴파일 시점에 몽땅 로딩하는 것이 아니라, 클래스가 처음 호출되는 시점에 각각 동적으로 로딩된다.

- 로딩된 바이트 코드는 Runtime Data Area에 실행가능한 상태로 배치된다

- ClassNotFoundException 예외가 발생하는 이유는 바로 클래스 로더가 라이브러리 또는 클래스를 찾지 못했기 때문.

 

(1) Bootstrap Class Loader

- JVM 실행 시 가장 먼저 실행되는 클래스 로더

- JVM 런타임 실행을 위해 기반이 되는 파일을 로드한다 (rt.jar 파일과 같은 핵심 라이브러리 파일과 연관). 말 그대로 부팅을 위한 최소한의 로드를 한다.

- 자바의 최상위 객체인 Object도 이때 로드된다

 

(2) Extension Class Loader (확장 클래스 로더)

- Bootstrap Class Loader를 포함하면서 자바 API를 로드한다.

 

(3) System Class Loader

- Classpath에 포함된 클래스들을 로드. (즉, 내가 작성한 클래스를 로드)

 

(4) User-Defined Class Loader는 classpath 외 임의의 경로에 위치한 클래스를 로드하고자 할 때 사용된다.

 

 

<클래스 로더의 특징>

1계층적 구조를 갖는다

 

2. 클래스 로딩을 위임할 수 있다. (위임 원칙)

- 부트스트랩 클래스 로더부터 순차적으로 내려가면서 클래스가 존재하는지 확인한다. 존재하지 않는 경우에는 하위 클래스에게 로딩을 위임한다.

- 맨 아래 시스템 클래스 로더에서도 클래스를 찾지 못한 경우에 ClassNotFoundException을 던진다.

 

3. 로딩 가능한 범위를 갖는다 (가시성 원칙)

- 하위 클래스 로더는 상위 클래스 로더가 로딩한 클래스를 찾을 수 있지만, 상위 클래스 로더는 하위 클래스 로더가 로딩한 클래스를 찾을 수 없다

- Object 클래스와 같이 상위 클래스 로더에서 로드된 클래스가 하위 클래스 로더에서 사용될 수 있는 이유. 클래스 로더간 상하위 관계를 만들어주는 원칙

 

4. 이미 로드된 클래스를 다시 로드하지 않는다 (유일성의 원칙)

- 상위 클래스 로더에서 로드된 클래스는 하위 클래스 로더에서 다시 로드될 수 없다.

-> 각각 고유한 클래스 하나만 존재함을 보장

 

5. 클래스를 언로딩 할 수 없다.

 

 

<클래스 로더의 동작 순서>

1. Runtime Data AreaMethod 영역에 클래스가 로드되어 있는지 확인. 있다면 그걸 사용

2. 시스템 클래스 로더 -> 확장 클래스 로더 -> 부트스트랩 클래스 로더 순으로 클래스 로드 요청 위임

3. 부트스트랩 클래스 로더부터 하위 클래스 로더 순으로 클래스가 존재하는지를 탐색

4-1. 시스템 클래스 로더에서까지 클래스를 찾지 못하면 ClassNotFoundException 던짐 

4-2. 클래스를 찾았다면 Runtime Data Area 중 Method 영역 클래스 정보를 추가(로딩)한다.

 

 

(++ 5 ++) 로딩을 마친 이후 힙 영역에 해당 클래스 타입의 Class 객체를 따로 생성★한다. (java.lang.Class<T>)

- 내가 new 키워드를 통해 생성한 것이 아님!! JVM이 자동으로 생성한다. 정말 몰랐던 사실!!!

https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html

Class has no public constructor.
Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the define Class method in the class loader.

-> 추후 Reflection을 이용해 "힙 영역에 저장된" Class 객체를 가져다가 사용할 수 있다.

(클래스 이름.class 과 같은 방법을 이용해)

 

 

(+) 그럼 클래스는 언제 로딩되는가?

1. 클래스의 인스턴스가 생성될 때

2. 클래스의 정적 변수(final X)가 사용될 때 (= static final 변수는 사용해도 클래스가 로딩되지 않는다!!)

3. 클래스의 정적 메서드가 호출될 때

 

 

(+) Runtime Data Area에 배치된 바이트 코드는 Execution Engine에 의해 실행된다

1. Entry Point(진입점)인 main 메서드가 Method Area에 제일 먼저 올라간다 (static)

2. main 메서드 속 지역변수는 Stack에, 동적 변수와 객체는 Heap에 저장된다

3. 메서드가 호출되면 새로운 스택을 생성하고, 메서드가 종료되면 스택을 비우고 제거한다

4. 참조가 끊어진 객체는 Heap 영역을 관리하던 GC가 수거해간다

 

이제 위 그림이 이해가 어느정도 되는 듯 하다. ㅎㅎ

 

 

(참고)

https://steady-coding.tistory.com/593

 

[Java] JVM의 클래스 로더란?

java-study에서 스터디를 진행하고 있습니다. 클래스 로더란? 자바는 동적 로드, 즉 컴파일 타임이 아니라 런타임(바이트 코드를 실행할 때)에 클래스 로드하고 링크하는 특징이 있다. 이 동적 로드

steady-coding.tistory.com

https://it-mesung.tistory.com/196

 

[The Java] 클래스 로더와 JVM

Java 프로그램의 실행 과정 Java 프로그램을 실행하면 JVM은 OS로 부터 메모리를 할당받는다. 작성한 .java 파일은 컴파일러에 의해 .class(바이트 코드) 파일로 변환된다. 클래스 로더에 의해서 .class(

it-mesung.tistory.com

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함