🍓 개요
메모리에서의
Stack
과 Heap
, 그리고 static
변수와 scope
의 개념은 프로그래밍에서 변수와 데이터가 처리되는 방식을 설명하는 중요한 개념들이다. 이는 프로그램의 메모리 관리 및 변수의 가시성과 수명에 관한 규칙을 정의한다. 오늘은 예제 코드와 함께 이 요소들의 활성화 되는 과정과 관계를 설명해보겠다. 예제 코드 :
🍋 메모리 구조 활성화 과정
예제 코드의 메모리 상태의 시각화 모습
1. 클래스 로드
제일 먼저 작업을 시작하기에 앞서서 어떤 작업을 해야 하는 클래스를 먼저 메모리에 띄울 수 있도록 클래스를 로드를 한다.
2. Static (정적 변수) 활성화
설명: 클래스가 로드되고 난 후
main
메서드가 실행되기 전에 이 정적 변수들이 메모리에 할당되고 초기화 된다. 이 변수들은 프로그램이 종료될 때까지 유지되며, 남발하게 되면 메모리 누수가 일어날 수 있으므로 조심해야 한다. - 코드 예시: 위의 코드에서 메인이 시작되기전 메모리에 로드된 정보들
static int n2 = 2; static void m1() public static void main(String[] args)
3. 메인 메서드 활성화 및 메인 큐
설명 : 정적 변수의 할당후,
main
메서드가 호출되면서 Stack
메모리에 할당이 된다. 그와 함께 자동으로main queue
역시 자동 생성이 되며 queue에서 순차적으로 코드 라인을 실행해 나간다. 이렇게 main
작업 처리 순서인 queue
에 들어오는 것을 이를 enqueue
라고 칭하고, 실행후 pop
되게 되면 dequeue
라고 한다, 메인 메서드에서 queue는 First In First Out
으로 처리해 나간다. - 코드 예시 :
public static void main(String[] args) { System.out.println(1); -----------------------------(1)-------- m1();-----------------------------------------------(2) System.out.println(2);------------------------------(3) main ScopeEx01_01 sc = new ScopeEx01_01();---------------(4) Queue System.out.println(sc.n1);--------------------------(5) sc.m2();--------------------------------------------(6)-------- }
예쁘지 않은 그림이지만, 해당 그림처럼 메인 메소드가 실행되면 그 안의 코드들이 모두
push
가 되어 순차적으로 메인 메소드 아래의 코드라인이 실행되어 처리됨과 동시에 pop
이되면서 나가게 되는 것이다.4. 함수 호출 순서와 메모리 할당 과정
첫 번째 호출
main
메서드 내에서 함수를 호출하면, 이 함수에 대한 스택 프레임이 생성된다. 이때, 함수의 매개변수와 지역 변수가 스택 메모리에 push
되고 실행되며 pop
이된다. System.out.println(1)
이 문장이 실행될 때, println
메소드에 대한 정보와 이 메소드에 전달되는 인자 1
이 스택에 저장된다.- 코드 예시:
public static void main(String[] args) { System.out.println(1); <-----------------------------queue
두 번째 호출
m1()
메소드가 호출될 때, 이 메소드에 대한 정보가 스택에 저장된다. 만약 m1
메소드 내부에서 지역 변수가 사용된다면, 이 지역 변수들도 스택에 저장된다. 이렇게 메소드가 호출될 경우에는 처리시스템이 branch
가 되면서 갈라지며, m1()
메소드의 queue
를 형성하게 된다. - 코드 예시:
main queue
public static void main(String[] args) { System.out.println(1); m1(); <----------------------------queue // m1()메소드가 호출 되면서 m1 queue가 새로 생기게됨.
- 코드 예시:
m1 queue
static void m1(){ int n5 = 10; System.out.println("m1 : " + n5); } //static에 할당 될때는 m1이름만 할당되고, 호출이 되어야 중괄호가 열리게 된다. // 이렇게 새로 생긴 m1 queue가 완료가 되면 다시 main queue로 복귀한다.
세 번째 호출
System.out.println(2)
이 문장이 실행될 때, println
메소드에 대한 정보와 인자 2
가 스택에 저장된다.- 코드예시 :
public static void main(String[] args) { System.out.println(1); m1(); System.out.println(2); <--------------------- queue
네 번째 호출
ScopeEx01
객체가 생성이 된다. ScopeEx01
객체가 생성될 때, 생성자에 대한 정보인 참조값 sc
가 스택 메모리에 저장된다. 이 경우 객체 자체(또는 값)는 힙 메모리에 저장되지만, 생성자는 스택 메모리에서 참조변수로 제어를 하게 된다. - 코드예시 :
public static void main(String[] args) { System.out.println(1); m1(); System.out.println(2); ScopeEx01_01 sc = new ScopeEx01_01();<-------------- queue
다섯 번째 호출
System.out.println(sc.n1)
이 문장이 실행될 때, println
메소드에 대한 정보와 이 메소드에 전달되는 인자 sc.n1
(객체 sc
의 인스턴스 변수 n1
)이 스택에 저장된다. 즉 현재 초기화 되어있는 필드 값 n1 = 1
에 1
이 출력된다.- 코드예시 :
public static void main(String[] args) { System.out.println(1); m1(); System.out.println(2); ScopeEx01_01 sc = new ScopeEx01_01(); System.out.println(sc.n1); <----------------------- queue
여섯 번째 호출
객체
sc
의 m2
메소드가 호출될 때, 이 메소드에 대한 정보와 이 메소드 내부에서 사용되는 지역 변수들이 스택에 저장
됩니다. 그리고 m2()
메소드 괄호안의 실행문 들을 m2 queue
로 관리하며 실행시키고 pop
이 되게 됩니다. - 코드예시 :
public static void main(String[] args) { System.out.println(1); m1(); System.out.println(2); ScopeEx01_01 sc = new ScopeEx01_01(); System.out.println(sc.n1); sc.m2(); <-------------------------- push
함수가 종료되고 결과를 반환하면, 함수에 의해 생성된 스택 프레임은 스택에서
팝(pop)
되어 제거가 된다. 이때, 함수의 지역 변수와 매개변수도 스택에서 제거된다.이러한 순서와 방식으로 각 개념이 프로그램 실행 도중 활성화되고 사용된다. 다시 간략히 설명하자면, 정적 변수
(static)
는 프로그램 시작 시 초기화되고, 함수가 호출될 때마다 새로운 스택 프레임이 생성되어 매개변수
와 지역 변수
가 스택 메모리
에 저장된다. 함수의 스코프
, (즉, 해당 변수가 사용될 수 있는 지역) 지역 변수의 생명 주기를 결정하며, 함수가 종료되면 이들 변수는 스택에서 제거된다.Share article