자바/Java JVM 메모리 구조
응용프로그램이 실행되면, JVM은 시스템으로부터 프로그램을 수행하는데 필요한 메모리를 할당받고 JVM은 이 메모리를 용도에 따라 여러 영역으로
나누어 관리한다.
그 중 3가지 주요영역(Method Area, 호출스택, Heap)에 대해서 알아보도록 하자.
[참고] cv는 클래스변수, lv는 지역변수, iv는 인스턴스변수를 뜻한다.
이 때, 그 클래스의 클래스변수(class variable)도 이 영역에 함께 생성된다.
각 메서드를 위한 메모리상의 작업공간은 서로 구별되며, 첫 번째로 호출된 메서드를 위한 작업공간이 호출스택의 맨 밑에 마련되고, 첫 번째 메서드 수행중에 다른 메서드를 호출하게 되면, 첫 번째 메서드의 바로 위에 두 번째로 호출된 메서드를 위한 공간이 마련된다.
이 때 첫 번째 메서드는 수행을 멈추고, 두 번째 메서드가 수행되기 시작한다. 두 번째로 호출된 메서드가 수행을 마치게 되면, 두 번째 메서드를 위해 제공되었던 호출스택의 메모리공간이 반환되며, 첫 번째 메서드는 다시 수행을 계속하게 된다. 첫 번째 메서드가 수행을 마치면, 역시 제공되었던 메모리 공간이 호출스택에서 제거되며 호출스택은 완전히 비워지게 된다.
호출스택의 제일 상위에 위치하는 메서드가 현재 실행 중인 메서드이며, 나머지는 대기상태에 있게 된다.
따라서, 호출스택을 조사해 보면 메서드 간의 호출관계와 현재 수행중인 메서드가 어느 것인지 알 수 있다.
호출스택의 특징을 요약해보면 다음과 같다.
- 언제나 호출스택의 제일 위에 있는 메서드가 현재 실행 중인 메서드이다. - 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드이다. |
[예제6-6] CallStackTest.java |
|
[실행결과] |
secondMethod() |
(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메서드의 수행이
완료되어 호출스택에서 사라지고 자신을 호출한 secondMethod()로 되돌아간다. 대기 중이던 secondMethod()는
println메서드를 호출한 이후부터 수행을 재개한다.
(7) secondMethod()에 더 이상 수행할 코드가 없으므로
종료되고, 자신을 호출한 firstMethod()로 돌아간다.
(8) firstMethod()에도 더 이상 수행할 코드가 없으므로
종료되고, 자신을 호출한 main메서드로 돌아간다.
(9) main메서드에도 더 이상 수행할 코드가 없으므로 종료되어, 호출스택은 완전히
비워지게 되고 프로그램은 종료된다.
[예제6-7] CallStackTest2.java |
class CallStackTest2 { public static void main(String[] args) { System.out.println("main(String[] args)이 시작되었음."); firstMethod(); System.out.println("main(String[] args)이 끝났음."); } static void firstMethod() { System.out.println("firstMethod()이 시작되었음."); secondMethod(); System.out.println("firstMethod()이 끝났음."); } static void secondMethod() { System.out.println("secondMethod()이 시작되었음."); System.out.println("secondMethod()이 끝났음."); } } |
[실행결과] |
main(String[] args)이 시작되었음. firstMethod()이 시작되었음. secondMethod()이 시작되었음. secondMethod()이 끝났음. firstMethod()이 끝났음. main(String[] args)이 끝났음. |
'JAVA > 개념정리' 카테고리의 다른 글
자바/Java instanceof 연산자란? (1) | 2013.01.14 |
---|---|
자바/Java 자바 용어 정리 ~! (0) | 2013.01.03 |
자바/Java break문, contunue문, 이름 붙은 반복문 사용법 (0) | 2012.07.12 |
자바/Java static의 사용법과 개념예 (2) | 2012.07.03 |
자바/Java ArrayList<T> 제네릭스(Generics)란? (20) | 2012.03.13 |