응용프로그램 실행 -> JVM은 시스템으로부터 프로그램을 수행하는데 필요한 메모리를 할당받고 JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.
3가지 주요 영역(method area, call stack, heap)
1. 메서드 영역(method area)
- 프로그램 실행 중 어떤 클래스가 사용되면, JVM은 해당 클래스의 클래스 파일(*.class)을 읽어서 분석하여 클래스에 대한 정보(클래스 데이터)를 이곳에 저장한다. 이 때, 그 클래스의 클래스변수(class variable)도 이 영역에 함께 생성된다.
- 클래스변수 : 인스턴스 변수 앞에 static을 붙이기만 하면 된다.
- 클래스변수는 모든 인스턴스가 공통된 저장공간(변수)을 공유하게 된다.
2. 힙(heap)
- 인스턴스가 생성되는 공간, 프로그램 실행 중 생성되는 인스턴스는 모두 이곳에 생성된다. 즉, 인스턴스변수(instance variable)들이 생성되는 공간이다.
- 인스턴스변수 : 클래스 영역에 선언되며, 클래스의 인스턴스를 생성할 때 만들어진다.
class Card {
String kind;
int number; // 인스턴스 변수
static int width = 100;
static int height = 250; // 클래스 변수
}
3. 호출스택(call stack 또는 exexcution stack)
- 호출스택은 메서드의 작업에 필요한 메모리 공간을 제공한다.
- 메서드가 호출되면, 호출스택에 호출된 메서드를 위한 메모리가 할당되며, 이 메모리는 메서드가 작업을 수행하는 동안 지역변수(매개변수 포함)들과 연산의 중간결과 등을 저장하는데 사용된다.
- 그리고 메서드가 작업을 마치면 할당되었던 메모리공간은 반환되어 비워진다.
- 호출스택의 특징
- 메서드가 호출되면 수행에 필요한 만큼의 메모리를 스택에 할당받는다.
- 메서드가 수행을 마치고나면 사용했던 메모리를 반환하고 스택에서 제거된다.
- 호출스택의 제일 위에 있는 메서드가 현재 실행 중인 메서드이다.
- 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드이다.
public class CallStackTest {
public static void main(String[] args) {
firstMethod(); // static 메서드는 객체 생성없이 호출이 가능
}
private static void firstMethod() {
secondMethod();
}
private static void secondMethod() {
System.out.println("secondMethod()");
}
}
설명
- main()이 firstMethod()를 호출하고 firstMethod()는 secondMethod()를 호출한다.
- 호출스택의 변화
- JVM에 의해서 main메서드가 호출됨으로써 프로그램이 시작. 호출 스택에는 main메서드를 위한 메모리 공간이 할당되고 main메서드의 코드가 수행되기 시작((1)~(2))
- main메서드에서 firstMethod()를 호출한 상태이다. 아직 main메서드가 끝난 것은 아니므로 main메서드는 호출스택에 대기상태로 남아있고 firstMethod()의 수행이 시작
- firstMethod()에서 다시 secondMethod()를 호출했다. firstMethod()는 secondMethod()가 수행을 마칠 때까지 대기상태에 있게 된다. secondeMethod()가 수행을 마쳐야 firstMethod()의 나머지 문장들을 수행할 수 있기 때문
- secondMethod()에서 println()을 호출했다. println메서드에 의해 'secondMethod()'가 화면에 출력된다.
- println메서드의 수행이 완료되어 호출스택에서 사라지고 자신을 호출한 secondMethod()로 되돌아간다. 대기 중이던 secondMethod()는 println()을 호출한 이후부터 수행을 재개한다.
- secondMethod()에 더 이상 수행할 코드가 없으므로 종료되고, 자신을 호출한 firstMethod()로 돌아간다.
- firstMethod()에도 더 이상 수행할 코드가 없으므로 종료되고, 자신을 호출한 main메서드로 돌아간다.
- main메서드에도 더 이상 수행할 코드가 없으므로 종료되어, 호출스택은 완전히 비어지게 되고 프로그램은 종료된다.
public class CallStackTest {
public static void main(String[] args) {
System.out.println("main(String[]args)이 시작되었음.");
firstMethod(); // static 메서드는 객체 생성없이 호출이 가능
System.out.println("main(String[]args)이 끝났음.");
}
private static void firstMethod() {
System.out.println("firstMethod()이 시작되었음.");
secondMethod();
System.out.println("firstMethod()이 끝났음.");
}
private static void secondMethod() {
System.out.println("secondMethod()이 시작되었음.");
System.out.println("secondMethod()");
System.out.println("secondMethod()이 끝났음.");
}
}
- 각 메서드의 시작과 종료의 순서를 확인하는 예제
'JAVA개념' 카테고리의 다른 글
예외처리(exception handling) (0) | 2021.11.30 |
---|---|
메서드를 사용하는 이유 (0) | 2021.11.28 |
클래스와 객체 (0) | 2021.11.28 |
객체지향언어의 주요특징 (0) | 2021.11.28 |
next()와 nextLine() 차이 (0) | 2021.11.28 |