Post

메모리 구조

Method(Static) 영역

  • JVM이 동작해서 클래스가 로딩 될 때 생성
  • JVM이 읽어들인 클래스와 인터페이스에 대한 런타임 상수 풀, 멤버 변수(필드), 클래스 변수(Static 변수), 상수, 생성자와 메소드 등을 저장하는 공간
  • Method(Static) 영역에 있는 것은 어느 곳에서나 접근 가능
  • Method(Static) 영역의 데이터는 프로그램의 시작부터 종료가 될 때까지 메모리에 남음.
  • 더 자세한 내용은

Stack 영역

  • 메소드 내에서 정의하는 기본 자료형(int, double, long … 등등)에 해당되는 지역변수(매개 변수 및 블럭문 내 변수 포함)의 데이터의 값이 저장되는 공간이 Stack 영역이다. 해당 메소드가 호출될 때 메모리가 할당되고 종료되면 메모리가 해제된다.
1
2
3
4
5
6
7
8
9
public class StackAreaEx {
	public static void main(String[] args) {
		int a = 5;	a = 4;	a = 3;	a = 2;
		System.out.println(a);
		for(int i=0; i<5; i++){
		}
//		System.out.println(i); 컴파일 에러
	}
}

위의 소스 코드처럼 a라는 변수는 main 메소드가 호출될 때 stack 영역에 할당되고 종료 시 해제된다.

a는 선언한 순서대로 5 -> 4 -> 3 -> 2 순으로 할당되고 마지막에 할당된 2가 출력된다. 이전 데이터는 지워지고 2가 출력되는 것이다.

즉 , stack 영역은 LIFO(Last In First Out)의 구조를 갖고 변수에 새로운 데이터가 할당되면 이전 데이터는 지워진다.

stack

또한 for 문 내에 정의한 int i 변수 또한 for 문이 종료되었기 때문에 지역변수인 i는 stack 영역에서 해제돼 컴파일 에러가 뜨는 것이다.

Heap 영역

참조형(Reference Type/ 메모리 주소)의 데이터 타입을 갖는 객체, 배열 등은 Heap 영역에 데이터가 저장된다.

이때 변수(객체, 객체변수, 참조변수)는 Stack 영역의 공간에서 실제 데이터가 저장된 Heap 영역의 참조값(reference value, 해시코드 / 메모리에 저장된 주소를 연결해주는 값) new 연산자를 통해 리턴 받는다. 다시 말하면 실제 데이터를 갖고 있는 Heap 영역의 참조 값을 Stack 영역의 객체가 갖고 있다. 이렇게 리턴 받은 참조 값을 갖고 있는 객체를 통해서만 해당 인스턴스를 핸들 할 수 있다.

1
2
3
4
5
6
7
8
9
public class HeapAreaEx01 {
	public static void main(String[] args) {
		int[] a = null; // int형 배열 선언 및 Stack 영역 공간 할당
		System.out.println(a); // 결과 : null
		a = new int[5]; // Heap 영역에 5개의 연속된 공간 할당 및 
		                // 변수 a에 참조값 할당
		System.out.println(a); // 결과 : @15db9742 (참조값)
	}
}

a 변수는 데이터가 저장된 Heap영역의 참조 값을 리턴 받아온다.

1
2
3
4
5
6
7
8
9
10
11
public class HeapAreaEx02 {
	public static void main(String[] args) {
		String str1 = new String("joker");
		String str2 = new String("joker");
		if(str1 == str2){
			System.out.println("같은 주소값 입니다.");
		}else{
			System.out.println("다른 주소값 입니다.");
		}
	}
}

new 연산자를 이용해서 생성하면 같은 자료형의 같은 값을 가지고 있더라도 서로 다른 참조 값을 가진다. 그렇기 때문에 출력 시 “다른 주소값 입니다.” 라는 결과가 나온다.

1
2
3
4
5
6
7
8
9
10
class A{}

public class HeapArea {
	public static void main(String[] args) {
		A a = null; // A타입의 a객체 선언 및 Stack 영역 공간 할당
		System.out.println(a); // 결과 : null
		a = new A(); // Heap 메모리에 공간 할당 및 객체(a)에 참조값 할당
		System.out.println(a); // 결과 : @15db9742
	}
}

이렇듯 객체도 참조 값을 가지고 있다.

메모리

Heap은 JVM의 GC에 의해 관리되기 때문에 메모리 해제에 개발자가 직접 신경 쓸 필요가 없다. 하지만 Stack의 경우 모든 동작이 완료되면 메모리에서 사라진다.

Stack vs Heap

  • Stack

    • 정적 메모리 할당
    • 함수의 호출과 관계되는 지역 변수와 매개변수가 저장되는 영역
    • 함수의 호출과 함께 할당되며, 함수의 호출이 완료되면 소멸
    • 푸시(push) 동작으로 데이터를 저장하고, 팝(pop) 동작으로 데이터를 인출
    • 후입선출(LIFO, Last-In First-Out) 방식
    • 메모리의 높은 주소에서 낮은 주소의 방향으로 할당

    장점

    • 매우 빠른 액세스(할당,해제가 빠르다)
    • 변수를 명시적으로 할당 해제 할 필요가 없다.

    단점

    • 메모리 크기 제한
    • 지역 변수만
  • Heap

    • 동적 메모리 할당
    • 사용자가 직접 관리할 수 있는 ‘그리고 해야만 하는’ 메모리 영역
    • 사용자에 의해 메모리 공간이 동적으로 할당되고 해제
    • 메모리의 낮은 주소에서 높은 주소의 방향으로 할당

    장점

    • 변수는 전역적으로 액세스 할 수 있다.
    • 메모리 크기 제한이 없다. 단점
    • 상대적으로 느린 액세스(할당,해제가 느리다)
    • 메모리를 관리해야 한다.(변수를 할당하고 해제하는 책임이 있다)
    • 운영체제마다 메모리 관리가 다르기 때문에 어렵다.

출처)

힙 영역 vs 스택 영역 (velog.io)

JAVA/자바] 메모리 구조(static, stack, heap) : 네이버 블로그 (naver.com),

https://blog.naver.com/chlwlstjd10/222239136195

This post is licensed under CC BY 4.0 by the author.