자바의 메모리 모델

gustjtmd·2022년 2월 2일
0

Java

목록 보기
14/40

자바 가상머신의 메모리 모델

가상머신은 운영체제 위에서 동작한다

자바 가상머신은 운영체제 위에서 실행되는 하나의 프로그램이다.
자바 프로그램은 자바 가상머신 위에서 실행되는 프로그램이다.

가상머신의 실행에 필요한 메모리는 어떻게 제공되는 것일까?
프로그램의 실행에 필요한 메모리 공간을 가리켜 '메인 메모리'라 하며 이는 물리적으로
램을 의미한다. 그리고 이 메모리 효율적인 사용을 위해서 윈도우, 리눅스 같은 운영체제가
메모리를 관리한다. 즉 운영체제가 응용 프로그램에게 메모리를 할당해 주는것

자바 가상머신의 메모리

가상머신은 운영체제로부터 할당받는 메모리 공간의 효율적인 사용을 고민해야 한다.
그렇다면 효율적인 메모리 공간의 사용 방법은 무엇일까? 
분류해서 저장을하면 찾을때 쉽게 빨리 찾을수 있는데
가상머신도 프로그램의 실행을 위해서 메모리 공간을 나누고 데이터를 특성에 따라 구분해서
저장한다.

위 그림에서 보이듯이 가상머신은 메모리 공간을 크게 세 개의 영역으로 나눈다 
그리고 각각의 메모리 영역에는 다음의 데이터들을 저장한다

1. 메소드 영역		'메소드의 바이트코드, static 변수'
2. 스택 영역		'지역변수, 매개변수'
3. 힙 영역		'인스턴스'

메소드 영역

소스파일을 컴파일할때 생성되는 자바 가사엄신에 의해 실행이 가능한 코드를 가리켜 '바이트코드'
라 한다. 그리고 이 바이트코드도 메모리 공간에 존재해야 실행이 가능하다
코드로 확인해보자

class Boy{
	static int average = 0;
    public void run() {...}
}
class MyMain{
	public static void main(String[] args){
    	Boy b = new Boy();	//인스턴스 생성
        Boy.average += 5;	//클래스 변수 접근
    }
}

위 main 메소드에서는 Boy 인스턴스를 생성하고 Boy의 클래스 변수에 접근하고 있다.
이렇듯 인스턴스의 생성 및 클래스 변수의 접근을 위해서는 해당 클래스의 바이트코드가 
메모리 공간에 로딩되어야 하는데 이때 로딩되는 메모리 공간이 '메소드 영역'이다., 메소드 영역은 특정 클래스의 정보가 메모리 공간에 올려질때 채워지는 영역

스택 영역

스택은 지역변수와 매개변수가 저장되는 공간이다. 이 둘은 다음의 공통점이 있다

"중괄호로 구분되는 지역 내에서만 유효한 변수들이다"

즉 중괄호 내에 할당된 이후에 해당 중괄호를 벗어나면 바로 소멸되는 특성의 데이터 저장을 위한
영역이 '스택'이다.

코드로 확인해보자

public static void main(String[] args){
	int num1 = 10;
    int num2 = 20;
    adder(num1, num2);
    System.out.println("...");
}
public static void adder(int n1, int n2){
	int result = n1 + n2;
    return result;
}

main 메소드가 호출되고 나서 변수 num1과 num2가 스택에 할당되고
adder 메소드가 호출되면서 매개변수 n1과 n2가 스택에 할당되고 이어서 변수 result도 
할당되었다.

그 후 메소드 adder를 빠져나오면 그 안에서 할당된 지역변수가 매개변수는 스택에서 
전부 소멸된다 (result, n2, n1)
이렇듯 지역변수와 매개변수는 선언되는 순간에 스택에 할당되었다가 자신이 할당된 영역을 벗어나면
소멸된다.

힙 영역

인스턴스는 힙 영역에 할당된다 왜 스택이 아닌 힙이라는 별도의 영역에 할당하는걸까?

그것은 인스턴스의 소멸 시점과 소멸 방법이 지역변수와 다르기 때문이다

public static void simpleMethod(){
	String str1 = new String("My String");
    String str2 = new String("Your String");
}

String 인스턴스의 생성문이 메소드 내에 존재하므로 str1과 str2는 참조변수이자 지역변수이다
따라서 이 둘은 스택에 할당된다 

그러나 인스턴스는 무조건 힙에 할당되니 메모리 공간에는 다음의 참조 관계가 형성된다.

이렇게 힙에 생성된 인스턴스들은 언제 소멸될까? 인스턴스의 소멸시기를 결정하는것은
가상머신의 역할이다. 가상머신이 인스턴스를 소멸시켜도 되겠다고 판단을 하면 자동으로 소멸된다.

그래서 자바는 다른 프로그래밍 언어에 비해 메모리 관리에 신경을 덜 써도 된다는 평가를 받는다.

자바 가상머신의 인스턴스 소멸시기

public static void simpleMethod(){
	String str1 = new String("My String");
    String str2 = new String("Your String");
    
    str1 = null;	//참조 관계 소멸
    str2 = null;	//참조 관계 소멸
}

위 코드에서 str1,str2에 null을 대입하였는데 이로써 두 String 인스턴스는 어느 참조변수도
참조하지 않는 상태가 되었다.

위와 같은 상태의 인스턴스는 존재할 이유가 없다 더 이상 접근할 수 없는 인스턴스이기 때문이다
때문에 이러한 상태의(아무런 참조변수도 참조하지 않는 상태의) 인스턴스는 
'소멸의 대상'이 되어 가상 머신에 의해 소멸이 이뤄진다.

이러한 인스턴스 소멸 방식을 가리켜 '가비지 컬렉션'이라 하며 이는 프로그래밍의 편의를 돕는
자바의 매우 특별한 기능이다.
힙 영역은 가상머신에 의한 가비지 컬렉션이 일어나는 메모리 공간이다.
profile
반갑습니다

0개의 댓글