Programming Language/JAVA

메모리 구조 - static/stack/heap

whdvlf94 2020. 3. 17. 16:58

static (data 영역)

  • JAVA 파일은 크게 필드(Field), 생성자(Constructor), 메서드(Method)로 구성되어 있다. 이 때, static 키워드가 붙은 필드(Field) 부분에서 선언된 변수(전역 변수) 또는 메서드정적(static) 멤버 이며, data 영역에 저장된다.
  • data 영역에 저장되어 있는 데이터는 프로그램 종료 시 까지 메모리에 남아있다.
package test4;

public class Static {

    static int Count;   // 정적 필드
    int a;  // 인스턴스 필드

    public Static() {
        this.Count ++;
        this.a ++;
        System.out.printf("Count : %s\t", this.Count);
        System.out.printf("a : %s\n", this.a);

    }

    public int display() {
       return a;
    }

    public static int getCount() {
        return Count;
    }


    public static void main (String[] args) {
        System.out.println(Count);
        // Static 클래스 정적(field) 필드 사용 가능
        // System.out.println(a);  Static 클래스 인스턴스 필드 사용 불가능
        Static st1 = new Static();
        Static st2 = new Static();

        st1.display();
        // 인스턴스 멤버 필요 시 인스턴스 생성 후 호출 가능

        System.out.println(Static.getCount());
        // Static 클래스 정적 메서드 사용 가능

        // System.out.println(Static.display());    Static 클래스 인스턴스 메서드 사용 불가능
    }
}

-------------------------------------------
0
Count : 1    a : 1
Count : 2    a : 1
2

- 정적 멤버는 클래스명으로 바로 사용이 가능하다.

ex) Static.Count , Static.GetCount()

- 정적 메서드에서는 정적 멤버만 사용 가능하다.

ex) this 키워드, 메서드 오버라이딩 사용 불가능

- 인스턴스 멤버 필요시 인스턴스 생성 후 호출 가능

 

stack (stack 영역)

  • 메서드 내에서 정의하는 지역 변수매개 변수가 저장되는 공간이 stack 영역이다.

  • stack 영역에 저장되어 있는 데이터는 메서드가 호출될 때 메모리에 할당되고, 종료 시 메모리가 소멸된다.

  • stack 영역LIFO(Last In First Out) 구조이다. 즉, 새로운 데이터는 stack의 최상위에 위치하게 되고, 데이터 추출 시, 가장 최근에 삽입된 데이터만(최상위) 접근이 가능하다.

public class Stack {
    public static void main(String[] args) {
        int a=5; a=4; a=3;
        System.out.println(a);    // 마지막 값인 3만 출력

        for(int i=0;i<5;i++) {    
            // 매개 변수 i, 메서드 혹은 함수에서 입력 값을 받을 때 사용되는 변수
            // 매개 변수도 메서드 내에서 선언된 것으로 간주되므로 지역 변수 이다.

            int j=i;
            // 지역 변수 j, 메서드 내에 선언되며 메서드 호출 시 생성되고, 종료 시 소멸된다.

        }
        System.out.println(i); // 컴파일 에러
       // 변수 i는 메서드 밖 공간에서는 종료되기 때문에 그 메모리는 소멸된다. 따라서 컴파일 에러 발생
    }
}

heap (heap 영역)

  • 참조형(Reference Type)의 데이터 타입을 갖는 객체(인스턴스), 배열 등은 heap 영역에 데이터가 저장된다.

  • 객체, 객체 변수, 참조 변수stack 영역에서 실제 데이터가 저장된 heap 영역의 참조값new 연산자를 통해 return 받는다.

    • new 연산자 : 클래스 타입인스턴스(객체)를 생성해주는 역할

      클래스          객체변수        =          new                클래스();
      
      자료형        참조값 저장            메모리(heap) 할당       생성자 호출
               (인스턴스 핸들)            인스턴스 생성,
                                   참조값 return(→객체)

      new 연산자를 통해 heap 영역에 데이터 저장 공간 할당 및 인스턴스를 생성한다. 이 후, 그 공간의 참조값을 객체에게 반환하고 생성자를 호출한다.

(※ 실제 데이터를 가지고 있는 heap 영역의 참조 값을 stack 영역의 객체가 가지고 있다.)

public class Heap {
    public static void main(String[] args) {
        int[] a= null;
        System.out.println(a); // null

        a = new int[3];    
        // new 연산자를 통해 heap 영역에 데이터 저장 공간을 할당하고, 인스턴스를 생성
        // 이 후, heap 영역의 참조값을 객체(a)에게 반환

        System.out.println(a);    // [I@723279cf(참조값)

           a = new int[3];
        System.out.println(a);    // [I@10f87f48(참조값)

        // 두 객체의 참조값이 다른 것을 확인할 수 있다.


}
}

※ new 연산자를 이용해서 생성하게 되면, 같은 값을 가진 객체이더라도 서로 다른 참조값을 리턴 받는 것을 확인 할 수 있다.

추가 개념 ) heap에 저장된 데이터가 더 이상 사용이 불필요하게 될 경우, 메모리 관리를 위해 JVM(Java 가상 머신)에 의해 자동으로 소멸된다.