티스토리 뷰

JVM (JAVA Virtual Machine) 이란 ?

  • 자바 가상 머신이라고 부릅니다.

  • 자바 바이트코드를 해당 운영체제의 기계어로 재번역하면서 실행시키는 주체

  • 운영체제와 자바를 연결시켜주는 역할

  • 자바 프로그램을 운영체제와 플랫폼 종류에 의존적이지 않게 독립적으로 동작할 수 있게 해주는 역할

  • 가비지 컬렉션(GC)을 통해 메모리 관리를 자동으로 해줍니다.

 


 

JAVA의 프로그래밍 과정

  1. 소스 코드를 작성합니다. ( 클래스명.java )

  2. JDK(Java Development Kit)가 제공하는 javac 컴파일러를 사용하여 바이트코드 형식으로 소스 코드를 컴파일합니다. ( 클래스명.class) 

  3. 실행 시 실행에 필요한 클래스들이 JVM에 연결되며 클래스 로더(Class Loader)가 컴파일된 바이트코드를 메모리로 읽어들입니다.

  4. 로드된 클래스들은 Runtime Data Area에 올라갑니다.

  5. 실행 엔진(Execution Engine)이 바이트코드를 한 줄씩 실행시킵니다.

 

JAVA의 프로그래밍 과정과 JVM의 메모리 구조

 


 

JVM 메모리 구조

Runtime Data Area

JVM이 운영체제 위에서 실행되면서 할당 받는 메모리 영역

크게 1. 쓰레드 별로 생성되는 데이터 영역과 2. 전체 쓰레드가 공유하는 데이터 영역으로 나뉩니다.

 

Runtime Data Area

 

1. 쓰레드 별로 생성되는 데이터 영역

쓰레드가 생성될 때 생성됩니다.

쓰레드가 종료되면 해제됩니다.

 

PC Register Area

  • 현재 수행 중인 JVM 명령의 주소값이 저장됩니다.

Stack Area

  • LIFO ( Last In First Out )

  • 메소드 내의 파라미터, 기본타입 지역변수, 연산 중 발생하는 임시 값들이 저장되는 곳

  • 메소드가 호출될 때마다 스택 프레임이 생성되고 이것이 쌓여 스택을 구성하게 됩니다.

  • 메소드 호출이 끝나면 ( = 닫는 괄호 '}' 가 실행되면 ) 함수가 종료되어 모두 pop 됩니다.

  • 기본타입 변수는 직접 값이 저장되고, 참조타입 변수는 주소값을 저장해두고 Heap 영역의 객체를 가리킵니다.

public class Test {

	public static void main(String[] args) {

		int num = 10;	// 1.
		num = opr(num); // 3.
	}

	// 2.
	public static int opr(int param) {

		int i = 1;
		int sum = param + i;

		return sum;
	}
}

stack 영역의 push, pop 과정

 

  1. main 메소드 실행 : num=10이 stack에 push

  2. opr 메소드가 호출 : param=10, i=1, sum=11이 stack에 순서대로 push

  3. opr 메소드 호출 끝남 : param=10, i=1, sum=11 모두 pop

  4. num값에 num=11 재할당

  5. main 메소드 호출 끝남 : num=11 pop

 

Native Method Stack

  • JAVA 외의 언어로 작성된 C/C++ 등의 코드를 수행하기 위한 stack

  • 언어에 맞게 C stack이나 C++ stack이 생성됩니다.

 

 

2. 전체 쓰레드가 공유하는 영역

JVM이 시작할 때 생성됩니다.

JVM이 종료되면 해제됩니다.

 

Heap Area

  • new 연산자로 생성된 객체 또는 배열이 저장되는 곳

  • 모든 Object 타입(String, List, Integer 등)이 생성되는 곳

  • 참조하는 변수나 필드가 없다면, 의미없는 객체가 되어 Garbage Collector에 의해 메모리에서 지워집니다.

String str = "안녕";
System.out.println(str + " : " + str.hashCode());

str += "하세요";
System.out.println(str + " : " + str.hashCode());

 

 

stack 영역과 heap 영역

String 타입으로 선언된 str 변수에 "안녕" 을 대입합니다.

str은 참조타입의 변수이기 때문에 stack에 저장되며 주소값만을 가지고 있습니다.

이 주소값을 통해 heap 영역에 저장된 "안녕" 이라는 값을 가리키게 됩니다.

 

이 때, String의 값을 수정하려고 할 때, String의 특징 중 immutable 하다는 특징이 중요합니다.

String은 값 수정 시 그 값 자체가 변경되는 것이 아니라, 새로운 값이 생성되고 그 값으로 참조를 바꾸게 됩니다.

따라서 "하세요"라는 문자열을 추가했을 때, 기존의 "안녕"이 저장된 주소값에 "하세요"를 이어붙이는 것이 아니라,

"안녕하세요" 라는 값이 담긴 새로운 객체를 생성하게 됩니다.

기존의 "안녕"은 더 이상 참조하는 변수가 없기 때문에 Garbage Collector에 의해서 메모리에서 지워지게 됩니다.

 

hashCode() 메소드로 두 str의 주소값을 비교해보면 "안녕" 과 "안녕하세요" 가 다르게 출력됩니다.

 

각 str의 주소값

 

Static Area ( = Method Area )

  • JVM에 의해 로드된 class 정보, 메소드 정보, field 부분에서 선언된 전역변수, 상수, static으로 선언된 변수와 메소드 정보들이 저장되는 곳

  • 해당 클래스에 대한 정보를 저장하는 곳이라고 보면 됩니다.

 

stack 영역과 heap 영역

 

  • 장점 : 모든 객체가 공유할 수 있습니다.

  • 단점 : Heap 영역과 달리 Garbage Collector의 영역 밖이기 때문에 프로그램이 종료될 때까지 메모리가 할당된 채로 존재하므로 프로그램에 악영향을 줄 수 있습니다.

 

Runtime Constant Pool

  • 런타임 상수 풀

  • Method 영역에 포함되지만 독자적 중요성을 띕니다.
  • 클래스와 인터페이스의 상수, 메소드와 필드에 대한 모든 레퍼런스들이 저장되는 곳

  • JVM은 이 런타임 상수 풀을 통해 해당 필드나 메소드의 실제 메모리 상 주소를 찾아서 참조하게 됩니다.

최근에 올라온 글
«   2024/07   »
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
Total
Today
Yesterday