JAVA stack & heap 차이점

정대기·2022년 6월 22일
0

JAVA PROGRAMING

목록 보기
6/15
post-thumbnail

메모리 구조

프로그램이 실행되기 위해서는 먼저 프로그램이 메모리에 로드 되어야한다.
또한, 프로그램에서 사용되는 변수들을 저장할 메모리도 필요하다.

따라서 컴퓨터의 운영체제는 프로그램의 실행을 위해 다양한 메모리 공간을 제공하고 있는데, 다음과 같다.

  1. 코드(code) 영역
  2. 데이터(data) 영역
  3. 스택(stack) 영역
  4. 힙(heap) 영역

Code 영역

실행할 프로그램의 코드가 저장되는 영역으로 text 영역이라고도 부른다. 컴파일 타임에 결정되고 중간에 코드를 바꿀 수 없게 Read-Only 로 지정되어있다.

Data 영역

코드에서 선언한 전역변수, static 변수등이 저장된 공간이다. 전역변수와 static값을 참조한 코드는 컴파일 후 Data영역의 주소값을 가르키도록 바뀐다. 실행 도중에 전역변수가 변경될 수 있어 이영역은 Read-Write로 지정되어있다.

Stack 영역

  • 함수의 호출과 함께 지역 변수 또는 매개변수 등이 할당
  • 정렬된 방식으로 메모리가 할당되고 해제 됨
  • 원시타입(int, double, float, boolean 등..)의 데이터가 실제 값과 함께 할당
  • Heap 영역에 생성된 Object 타입의 데이터의 참조값이 할당(실제 주소 저장)
  • 지역변수들은 scope에 따른 visibility를 가짐
  • 각 Thread는 자신만의 stack 을 가짐

heap 영역

  • 클래스 변수(또는 인스턴스 변수) 또는 객체 등이 할당
  • 우연하고 무질서하게 메모리가 할당(JVM은 무질서하게 관리되는 힙 영역을 위주로, 가비지 컬렉터를 통해 메모리의 해제를 관리 함)
  • 모든 메모리 중 stack에 있는 데이터를 제외한 부분
  • 모든 Object 타입(Integer, String, ArrayList, ...)은 heap 영역에 실제 값 할당
  • 주로 긴 생명주기를 가지는 데이터들이 저장(대부분의 obj는 크기가 크고 서로 다른 코드블럭에서 공유되는 경우가 많음)
  • 몇개의 Thread가 존재하든 상관없이 단 하나의 heap 영역만 존재

Stack 영역 예제

public class Main {
    public static void main(String[] args) {
        int num = 5;
        num = method(num);
    }

    private static int method(int parameter){
        int tmp = parameter * 2;
        int result = tmp / 5;
        return result;
    }
}

int num = 5; 에 의해 스택에 num이라는 변수명으로 공간이 할당된다.

num = method(num); 에 의해 method()함수가 호출된다.호출될때 인자로 num 변수를 넘겨주며 scope가 method()함수로 이동한다. scope 가 바뀌면서 기존의 num이라는값은 scope에서 벗어나므로 사용할 수 없다. 이때 인자로 넘겨받은 값은 파라미터인 parameter 에 복사되어 전달되는데, parameter 또한 값이 할당된다.

int tmp = parameter * 2;
int result = tmp / 5;

에 의해 이 두개의 변수도 스택에 할당된다.

다음으로, 닫는괄호 } 가 실행되어 method()함수호출이 종료되면 호출함수 scope 에서 사용되었던 모든 지역변수들은 stack 에서 pop(튀어나감) 된다. 스택의 상태는 아래와 같이 변한다.

num 변수는 5로 초기화 되었지만, 함수의 실행결과인 2가 기존 num변수에 할당되었다. 함수호출에서 사용되었던 지역변수들이 모두 pop되기 전에 재할당되고 main()함수도 종료되는 순간 stack 에 있는 모든 데이터들은 pop 되면서 프로그램이 종료된다.

Heap 예제

public class Main {
    public static void main(String[] args) {
        int port = 8080;
        String host = "localhost";
    }
}

int port = 8080;
에의해서 스택에 8080이란 값이 port라는 변수명으로 할당!

String 은 Object 를 상속받아 구현되었으므로 (Object 타입은 최상위 부모클래스다, Polymorphism 에 의해 Object 타입으로 레퍼런스 가능하다) String 은 heap 영역에 할당되고 stack 에 host 라는 이름으로 생성된 변수는 heap 에 있는 “localhost” 라는 스트링을 레퍼런스 하게 된다.

0개의 댓글