티스토리 뷰

반응형

프로그램이 메모리를 활용하는방법

객체 지향 프로그램에서 메모리 사용하는 방식에 대해 알아보겠습니다.

 

<그림 1 메모리 사용 방식>

 

프로그램이 실행 되면 메모리는 코드 실행 영역과 데이터 저장 영역으로 분할이 됩니다. 여기서 데이터 영역은 다시 Static 영역, Stack 영역, Heap 영역으로 분할이 됩니다.

 

여기에서 집중적으로 볼 것은 데이터 영역입니다.

 

Static 영역 - 프로그램에서 사용되는 패키지 및 클래스

 

Stack 영역 - main() 메서드를 포함 한 메서드들 및 블록구문

 

Heap 영역 - 객체

 

기본적으로 프로그램이 실행이 되면 모든 자바 프로그램이 공통적으로 가지는 java.lang 패키지와 사용자가 import 한 패키지 그리고 main 메소드를 포함하고 있는 class가 Static영역에 할당됩니다.

 

 

프로그램 동작과 메모리 변화 살펴보기

 

실제로 간단한 코드 실행 마다 메모리 구조의 변화에 대해 살펴 보겠습니다.

 

 

위의 프로그램은 main() 메서드에서 넘겨 준 인자 값에 10을 더해서 반환해주는 sum() 메서드를 호출하는 간단한 코드입니다. 각 코드라인을 실행시마다 메모리 구조를 살펴보겠습니다. (편의상 데이터 영역만 표시하도록 하겠습니다)

 

1. java.lang 패키지 및 Memory class Static 영역 할당

 

       <그림2 메모리 모습>

 

JVM은 프로그램이 시작되면 제일 먼저 java.lang 패키지와 Memory class를 Static 영역에 할당 합니다. 추가로 사용자 import 패키지도 할당을 하지만 위의 프로그램의 경우는 해당 안됩니다.

 

2. main 메서드를 위한 main() 스택 프레임 할당

 

<그림 3 메모리 모습>

 

main() 메소드의 시작 중괄호를 만나게 되면 main() 메서드를 위한 스택 프레임이 Stack 영역에 할당이 됩니다. 현재 main() 메소드를 호출하면서 넘겨주는 인자 값은 없기 때문에 args는 아무런 값이 들어가지 않습니다.

 

 

3. 변수 선언 및 초기화

 

<그림 4 메모리 모습>

 

7,8번 라인에서 변수 i와 j가 선언 및 초기화가 됩니다. 메모리 구조에서는 main() 메서드의 스택 프레임안에 각각의 변수가 할당 되는 것을 확인 할 수 있습니다.

 

4. sum() 메서드 호출

 

<그림 5 메모리 모습>

 

10 라인에서 sum() 함수를 호출 하고 있습니다. 역시나 sum() 메서드의 시작 중괄호를 만나면 Stack 영역에 sum() 메서드를 위한 스택 프레임이 형성이 됩니다. 제일 먼저 반환값을 넘겨주기 위한 영역이 할당이 되고 그 다음으로 차례차례 변수에 대한 메모리가 할당이 됩니다. 여기서 주목해야 할 점은 sum() 프레임과 main() 프레임은 서로 다른 영역이라는 것, 즉 sum() 스택에 있는 j변수와 main() 스택에 있는 j변수는 이름만 같을 뿐 서로 다른 변수라는 점입니다.

 

main() 메소드 내에서 다른 메서드에 있는 지역 변수를 쓰지 못하는 이유를 메모리 구조만 봐도 확실히 알 수 있습니다.

 

sum() 메서드가 끝나는 중괄호를 만나게 되면 해당 스택영역에서 사라지게 됩니다. 마찬가지로 main() 메서드 역시 끝나는 중괄호를 만나게 되면 스택영역에서 사라지게 됩니다.

 

 

전역 변수는 왜 쓰면 안될까?

 

우리가 흔히 static 키워드를 사용하여 선언하는 변수는 전역변수로 메모리 구조상 static 영역에 할당이 됩니다. 즉 Stack 영역의 각각의 스택 프레임이 공통으로 접근이 가능하다는 소리입니다.

 

그렇게 되면 모든 메서드 영역에서 이 전역변수에 대하여 조작이 가능하게 됩니다. 이러한 점에서 프로그램의 길이가 매우 길 경우에는 해당 전역변수의 값을 추적해나가기 힘들어지는 경우가 발생 할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형