지역변수와 메모리 : 스택프레임에 갇혔어요
Q. 변수와 메모리 : 변수! 넌 어디있니?
A. 메모리에 있다. 더 구체적으로는 T메모리 3영역 모두에 있다. 그런데 세 군데 각각에 있는 변수는 각기 다른 목적을 가진다.
- 지역변수 : 스택 영역에서 일생을 보낸다. (더 자세히는 스택프레임안) 따라서 스택 프레임이 사라지면 함께 사라진다.
- 클래스 멤버 변수 : 스태틱영역에서 일생을 본내다. 스태틱 영역에 한번 자리 잡으면 JVM이 종료될 때까지 고정된 상태로 있는다.
- 객체 멤버 변수 : 힙에서 일생을 보낸다. 객체와 함께 가비지컬렉터라고 하는 힙 메모리 회수기에 의해 사라지게 된다.
public class Start3 {
public static void main(String[] args) {
int i = 10;
int k = 20;
//System.out.println(m);
if(i==10) {
int m = k+5;
k = m;
//System.out.println(m);
}
else {
int p = k+10;
k = p;
}
//System.out.println(m);
//k=m+p;
}
}
- 5번째 줄이 주석과 같다면 “m cannot be resolved to a variable” 오류가 발생
- 13번재 줄이 주석과 같다면 “m cannot be resolved to a variable” 오류가 발생
- 7번째 줄이 주석과 같다면 컴파일 가능 if 블록 스택 프레임을 수행하는 중에 if블록 스택 프레임 외부에 존재하는 변수 k는 접근이 가능하다. 외부 스택 프레임에서 내부 스택 프레임의 변수에 접근하는 것은 불가능하나 그 역은 가능하다. 그래서 스택 메모리 내의 스택프레임 안의 변수를 지역변수라고 한다. 그 지역(스택 프레임)에서만 사용할 수 있기 때문이다.
메서드 호출과 메모리 : 메서드 스택 프레임2
public class Start4 {
public static void main(String[] args) {
int k = 5;
int m;
m = square(k);
}
private static int square(int k) {
int result;
k = 25;
result = k;
return result;
}
}
- 5번째 줄이 끝났을 때의 T메모리

- 6번째 줄, square()메서드를 호출하고 있다. 9번째 줄로 이동. 메서드 호출이 일어나면 무조건 호출되는 메서드의 스택 프레임이 T메모리 스택 영역에 새로 생성된다.
- k = 25까지 실행한 후 : main()메서드가 가진 변수 k와 square() 메서드가 가진 변수 k가 이름만 같지 별도의 변수공간이다. (call by value)

- return result 실행되면 호출한 쪽에 돌려줄 값을 가져야 할 반환값 변수에 result 변수에 담긴 값이 복사된다.
- square()메서드의 끝을 알리는 닫는 중괄호를 만나면 반환값을 돌려주면서 스택에서 사라진다.
Q. main() 메서드의 어디에선가 square() 매서드 내의 지역변수 result에 직접 접근할 수 있을까? 또는 반대로는 가능한가?
A. 절대 접근할 수 없다. 매서드를 블랙박스화 한다.(=입력값들과 반환값에 의해서만 메서드 사이에서 값이 전달될 뿐 서로 내부의 지역 변수를 볼 수 없다는 것)

- 자바에는 포인터가 없다!
메서드 사이에 값을 전달하거나 반환하는 방법은 메서드의 인자와 반환값으로만 가능하다는 사실을 기억해두자!
전역변수와 메모리 : 전역 변수 쓰지 말라니까요!
전역변수를 사용하는 것도 메서드 사이에 값을 전달하는 방법중 하나이다.
public class Start5 {
static int share;
public static void main(String[] args) {
share = 55;
int k = fun(5,7);
System.out.println(share);
}
private static int fun(int m, int p) {
share = m+p;
return m-p;
}
}
- share변수는 T메모리의 스태틱 영역에 변수공간이 할당된다. 해당 클래스가 T메모리 스태틱 영역에 배치될 때 그 안에 share변수가 클래스의 멤버로 공간을 만들어 저장된다.

- share=m+p; 줄이 시행되면, m변수와 p변수에 있는 값을 더해 share변수에 할당한 상태가된다.

- 메서드 밖에서 선언된 변수 share는 메서들 사이에서 공유해서 사용할 수 있는 전역 변수가 된다.
전역변수
- 스태틱 영역에 변수공간이 할당된다.
- 코드 어느 곳에서나 접근할 수 있다고 해서 전역변수라고 하며, 여러 메서드들이 공유해서 사용한다고 해서 공유 변수라고 한다.
- 프로젝트 규모에 따라 코드가 커지면서 여러 메서드에서 전역 변수의 값을 변경하기 시작하면 T메모리로 추적하지 않는 이상 전역 변수에 저자오대 있는 값을 파악하기 쉽지 않기 때문에 사용하지 않는 것이 좋다.
- 전역 상수로 쓰는 것은 적극 추천
멀티 스레드 / 멀티 프로세스의 이해
멀티스레드(multi thread)의 T 메모리 모델은 스택 영역을 스레드 개수만큼 분할해서 쓰는 것이다.

- 하나의 스레드에서 다른 스레드의 스택 영역에는 접근할 수 없지만 스태틱 영역과 힙 영역은 공유해서 사용하는 구조다.
- 멀티프로세스 대비 메모리를 적개 사용할 수 있는 구조
- 전역변수는 공유영역(스태틱과 힙)에 저장되기때문에 쓰기 가능한 전역변수를 사용하게 되면 스레드 안정성이 깨진다.
멀티 프로세스(multi process)는 다수의 데이터 저장 영역, 즉 다수의 T 메모리를 갖는 구조다.

- 각 프로세스마다 각자의 T메모리가 있고 각자 고유의 공간이므로 서로 참조할 수 없다.
- 하나의 프로세스가 다른 프로세스의 T메모리 영역을 절대 침범할 수 없는 메모리 안전한 구조이지만 메모리 사용량은 그만큼 크다.
자바 웹프로그래밍 : “서블릿은 요청당 프로세스가 아닌 요청당 스레드를 생성한다”, “요청당 스레드(servlet)가 요청당 프로세스(CGI) 보다 효율적”
STS(또는 이클립스)를 이용해 T 메모리 영역 엿보기
CHP2 정리
- 메서드를 만들 때는 순서도 또는 의사 코드를 작성하는 것이 좋다.
- 힙 영역은 객체가 상주하는 구역, 객체 지향이 힙 메모리 영역을 사용하는 방식은 기존의 절차적/구조적 언어와 차이가 있다.
'Spring' 카테고리의 다른 글
02.자바와 절차적/구조적 프로그래밍_1 (0) | 2022.10.02 |
---|