본문 바로가기

Java/Basic

[Java] JVM의 메모리 구조

응용 프로그램이 실행되면, JVM은 시스템으로부터 프로그램을 수행하는데 필요한 메모리를 할당받고 JMV은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.

 

cv는 클래스변수, lv는 지역변수, iv는 인스턴스 변수

1) 메서드 영역(Method Area)

- 프로그램 실행 중 어떤 클래스가 사용되면, JVM은 해당 클래스의 클래스파일(*.class)을 읽어서 분석하여 클래스에 대한 정보(클래스 데이터)를 이곳에 저장한다. 이 떄, 그 클래스의 클래스변수(class variable)도 이 영역에 함께 생성된다.

 

2) 힙(Heap)

인스턴스가 생성되는 공간, 프로그램 실행 중 생성되는 인스턴스는 모두 이 곳에 생성된다.

- 즉, 인스턴스 변수(intance variable)들이 생성되는 공간이다.

 

3) 호출 스택 (Call Stack 또는 Execution Stack)

- 호출스택은 메서드의 작업에 필요한 메모리 공간을 제공한다. 

- 메서드가 호출되면 Class Stack에 호출된 메서드를 위한 메모리가 할당되며, 이 메모리는 메서드가 작업을 수행하는 동안 지역변수(매개변수 포함)들과 연산의 중간결과 등을 저장하는데 사용된다. 그리고 메서드가 작업을 마치면 할당되었던 메모리공간은 반환되어 비워진다.

 

- 각 메서드를 위한 메모리 상의 작업공간은 서로 구별되며, 첫 번째로 호출된 메서드를 위한 작업공간이 호출스택의 맨 밑에 마련되고, 첫 번째 메서드 수행 중에 다른 메서드를 호출하면, 첫 번째 메서드의 바로 위에 두 번째로 호출된 메서드를 위한 공간이 마련된다.

- 이 때 첫 번째 메서드는 수행을 멈추고, 두 번째 메서드가 수행되기 시작한다. 두 번째로 호출된 메서드가 수행을 마치게 되면, 두 번쨰 메서드를 위해 제공되었던 호출스택의 메모리공간이 반환되며, 첫 번째 메서드는 다시 수행을 계속하게 된다. 첫 번째 메서드가 수행을 마치면, 역시 제공되었던 메모리 공간이 호출스택에서 제거되며 호출스택은 완전히 비워지게 된다.

- 호출스택의 제일 상위에 위치하는 메서드가 현재 실행 중인 메서드이며, 나머진느 대기상태에 있게 된다. 따라서 호출 스택을 조사해 보면 메서드 간의 호출관계와 현재 수행중인 메서드가 어느 것인지 알 수 있다. 

 

호출스택의 특징

 

- 반환타입(return type)이 있는 메서드는 종료되면서 결과값을 자신을 호출한 메서드(caller)에게 반환한다.

- 대기상태에 있던 호출한 메서드(caller)는 넘겨받은 반환값으로 수행을 계속 진행하게 된다.

 

실행결과 > scnodMethod() 호출

- main()이 firstMethod()를 호출하고 firstMethod()는 secondMethod()를 호출한다.

- 객체를 생성하지 않고도 메서드를 호출할 수 있으려면, 메서드 앞에 'static'을 붙여야 한다.

-

위 코드 실행 시 호출스택의 변화

(1)~(2)

 :  위의 예제를 실행시키면, JVM에 의해서 main메서드가 호출됨으로써 프로그램이 시작된다. 이 때, 호출스택에는 main메서드를 위한 메모리공간이 할당되고 main메서드의 코드가 수행되기 시작한다.

(3)

 : main메서드에서 firstMethod()를 호출한 상태이다. 아직 main메서드가 끝난 것은 아니므로 main메서드는 호출스택에 대기상태로 남아있고 firstMethod()의 수행이 시작된다.

(4) 

  : firstMethod()에서 다시 secondMethod()를 호출했다. firstMethod()는 secondMethod()가 수행을 마칠 때까지 대기상태에 있게 된다 secondMethod()가 수행을 마쳐야 firstMethod()의 나머지 문장들을 수행할 수 있기 때문이다.

(5)

 : secondMethod()에서 println을 호출했다. println메서드에 의해 'secondMethod()'가 화면에 출력된다

(6)

: println메서드의 수행이 완료되어 호출스택에서 사라지고 자신을 호출한 second Method()로 돌아간다. 대기 중이던 secondMethod()는 println()을 호출한 이후부터 수행을 재개한다.

(7)

 : secondMethod()에 더 이상 수행할 코드가 없으므로 종료되고, 자신을 호출한 firstMethod()로 돌아간다.

(8) 

 : firstMethod()에도 더 이상 수행할 코드가 없으므로 종료되고, 자신을 호출한 main메서드로 돌아간다.

(9)

 : main메서드에도 더 이상 수행할 코드가 없으므로 종료되어, 호출스택은 완전히 비워지게 되고 프로그램을 종료된다.