메모리 구조

맥모닝·2023년 11월 7일
0

Java

목록 보기
1/7
post-thumbnail

메모리 구조

  • 프로그램을 구동하기 위해서 운영체제가 메모리(RAM)에 데이터 및 명령어를 저장할 공간을 할당하여 준다.
  • 메모리는 컴퓨터에게 있어 가장 중요한 자산이고 사용할 수 있는 공간이 한정되어 있다.
  • 이러한 것을 어떻게 관리하느냐에 따라서 프로그램의 성능(속도 등)이 좌우된다.
  • 따라서 메모리를 효율적으로 사용하기 위해서는 메모리의 구성과 특징에 대해서 이해할 필요가 있다.
  • 메모리의 공간은 크게 Static 영역, Stack 영역, Heap 영역으로 구분되고 데이터 타입(자료형)에 따라서 해당 공간에 할당된다.

Static 영역 (스태틱 메모리 영역)

  • 하나의 Java 파일은 크게 필드(field), 생성자(constructor), 메소드(method)로 구성된다.
  • 그 중 필드 부분에서 선언된 변수(전역 변수)와 정적 멤버 변수(static이 붙은 자료형)이 Static 영역에 데이터를 저장한다.
  • Static 영역의 데이터는 프로그램의 시작부터 종료가 될 때까지 메모리에 남아있게 된다.
    • 즉, 전역 변수가 프로그램이 종료될 때까지 어디서든 사용이 가능한 이유를 의미한다.
  • 따라서 전역 변수를 무분별하게 많이 사용하다 보면 메모리가 부족할 우려가 있어 필요한 변수만 사용할 필요가 있다.

Stack 영역 (스택 메모리 영역)

  • 메소드 내에서 정의하는 기본 자료형(int, double, byte, long, boolean 등)에 해당되는 지역변수(매개 변수 및 블록문 내 변수 포함)의 데이터 값이 저장되는 공간이 Stack(스택) 영역이다.
  • 해당메소드가 호출될 때 메모리에 할당되고 종료되면 메모리가 해제된다.
public class StackAreaEx {
    public static void main(String[] args) {
        int a = 5; a = 4; a = 3; a = 2;
        System.out.println(a); // 2
        
        for (int i = 0; i < 5; i++) {
            /* ... */
        }
        // System.out.println(i); 컴파일 에러
    }
}
  • a라는 변수는 main 메소드가 호출될 때 Stack 영역에 할당되고 종료 시 해제된다.
  • Stack 영역은 LIFO(Last In First Out)의 구조를 갖고 변수에 새로운 데이터가 할당되면 이전 데이터는 지워진다.
  • for문이 종료된 다음 i를 출력하지 못하는 이유는 i는 지역변수여서 for문의 종료와 함께 Stack 영역에서 해제되었기 때문이다.

Heap area (힙 메모리 영역)

  • 참조형(Reference Type)의 데이터 타입을 갖는 객체(인스턴스), 배열 등은 Heap 영역에 데이터가 저장된다.
  • 이때 변수(객체, 객체 변수, 참조 변수)는 Stack 영역의 공간에서 실제 데이터가 저장된 Heap 영역의 참조값(reference value, 해시코드 / 메모리에 저장된 주소를 연결해주는 값)을 new 연산자를 통해 리턴 받는다.
    • 즉, 실제 데이터를 갖고 있는 Heap 영역의 참조 값을 Stack 영역의 객체가 갖고 있다.
  • 이렇게 리턴 받은 참조 값을 갖고 있는 객체를 통해서만 해당 인스턴스를 핸들 할 수 있다.
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 (참조값)
    }
}
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("다른 주소값 입니다.");
        }
    }
}
  • 문자열을 저장하는 String도 참조형이다. new 연산자를 이용해서 생성하면 데이터는 Heap 영역에 저장되고 str1과 str2는 참조 값을 리턴 받는다.
  • 저장된 주소가 다르기 때문에 "=="으로 비교시 "다른 주소값 입니다."가 출력되는 것이다.
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, 쓰레기 수집)이라고 한다.

참고 사이트

profile
필요한 내용을 공부하고 저장합니다.

0개의 댓글