학부에서 Java강의를 들으면, 'static'은 시험에서 단골문제입니다. 전에는 암기하기만 했던 'static'의 성질들을 JVM의 메모리구조부터 차근차근 살펴보며 이해하려 합니다. 왜 static이 그러한 성질을 갖게 되었는지 알아보겠습니다.

 

1. Java 응용프로그램 실행 순서

먼저, Java 응용프로그램이 실행되는 순서를 되짚고 가겠습니다.

(1) 운영체제로 부터 JVM이 사용할 메모리 할당받음
(2) javac.exe로 .java파일을 JVM이 실행할 수 있는 .class파일로 컴파일함
(3) java.exe로 main메서드 실행
(4) 실행 중 어떤 class가 필요할 때, 해당 .class파일을 읽어서 JVM이 할당받은 메모리에 올림.
(5) 모든 코드 실행 후 종료

이 순서로 실행됩니다. 신기했던 건, 프로그램 시작할 때가 아닌 실행 중에 필요한 .class파일을 메모리에 올린다는 점이었는데요. 클래스 로더라는 친구가 이 역할을 한다고 합니다. 

 

2. JVM 메모리 구조

그렇다면 어떤 형태로 .class파일을 읽어서 메모리에 올릴까요?

자료 : 'Java의 정석'

JVM은 위 그림처럼 메모리를 용도에 따라 대표적으로 3가지 영역으로 나누어 관리합니다. 그리고 이 중 'static'을 이해하기 위해서는 'Method Area'와 'Heap'에 대해 알아야합니다.

 

- Method Area

: 이 영역에는 클래스에 대한 정보가 저장됩니다. JVM은 해당 클래스가 필요할 때 .class파일을 읽어서 클래스에 대한 정보를 이곳에 저장합니다. 그리고 이 영역에 해당 클래스의 static변수static메소드 또한 생성됩니다.

- Heap

: 이 영역에는 인스턴스가 생성됩니다. 인스턴스가 생성될 때, 이 영역에 인스턴스 변수인스턴스 메소드가 생성됩니다.

 

예를 들어, 아래와 같은 클래스가 있습니다. 그리고 이 클래스는 실제 사용될 때 메모리에 올라갑니다.

public class Data {
	int x;
	static int y = 3;
	void m() {}
	static void s() {};
}

아래는 실제 사용될 때 입니다.

public static void main(String[] args) {
	//...
	Data data1; //Method Area에 Data클래스 생성
	data1 = new Data(); //Heap에 Data인스턴스(data1) 생성
	Data data2 = new Data(); //Heap에 Data인스턴스(data2) 생성
	//...
}

아래는 메모리에 로딩된 최종 결과 입니다.

정리하면

첫 번째로, 메모리에 생성되는 공간이 다릅니다. static변수와 메모리는 Method Area에, 인스턴스 변수와 메모리는 Heap에 생성됩니다.

두 번째로, 생성되는 시점이 다릅니다. static변수와 메모리는 클래스가 로딩되는 시점에 생성되는 반면, 인스턴스 변수와 메모리는 인스턴스가 생성될 때 생성됩니다.

세 번째로, 생성 횟수가 다릅니다. static변수와 메모리는 메모리에 한번만 올라가서 계속 있는 반면, 인스턴스 변수와 메모리는 새롭게 인스턴스가 생성될 때마다 메모리에 생성됩니다. 

 

3. static 성질 이해하기

저희가 이해한 것을 바탕으로 static의 성질들을 이해해보겠습니다.

 

- "static변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 갖는다"

: YES. 클래스의 static변수는 Method Area에 딱 하나 존재합니다. 인스턴스에서 참조하더라도 같은 공간을 참조하므로 항상 같은 값을 갖게됩니다.

 

- "static변수 및 메소드는 인스턴스를 생성하지 않아도 사용할 수 있다"

: YES. static변수와 메소드는 인스턴스가 생성되는 시점에 메모리에 올라가는 것이 아닌, 클래스가 메모리에 올라갈 때 생성됩니다.

 

- "static메소드는 인스턴스 변수나 메소드를 사용할 수 있다"

: NO. 클래스는 메모리에 로딩되었지만, 인스턴스는 없을 수 있습니다. 따라서, static메소드를 사용하는 시점에 인스턴스는 없을 수 있으므로 사용할 수 없습니다.

 

- "인스턴스 메소드는 static 변수나 메소드를 사용할 수 있다"

: YES. 인스턴스 메소드는 인스턴스가 생성되고 사용할 수 있습니다. 인스턴스가 생성되었다는 의미는 클래스가 메모리에 이미 로딩되었다는 뜻이므로 static변수와 메소드 또한 메모리에 로딩되었음을 의미합니다. 따라서, 사용할 수 있습니다.


시험에서 단골문제로 나왔던 'static' 성질 찾기. 위 예시 뿐만 아니라 여러가지 변형들이 무수히 존재합니다. 하지만, 메모리 관점에서 시작해서 static의 본질 이해하면 변형들도 쉽게 이해할 수 있으리라 생각합니다. 'static'을 공부하시는 분들께 도움이 됐으면 좋겠습니다~

'Java' 카테고리의 다른 글

JAR, WAR, EAR  (1) 2023.09.18
Garbage Collector  (0) 2023.09.15
JVM  (0) 2023.09.14
Abstract Class vs Interface  (0) 2023.09.13
[Java의 정석] JVM이란?  (0) 2023.04.01

+ Recent posts