봄디의 개발일지
[JAVA] 자바 메모리 구조 본문
🌟 자바 메모리 구조
자바의 메모리 구조는 크게 메서드 영역, 스택 영역, 힙 영역 3개로 나눌 수 있습니다.
- 메서드 영역 : 클래스 정보를 보관한다.
- 스택 영역 : 실제 프로그램이 실행되는 영역이다.
- 힙 영역 : 객체(인스턴스) 가 생성되는 영역이다. 배열도 이 영역에 생성된다.
✅ 메서드 영역
메서드 영역은 프로그램을 실행하는데 필요한 공통 데이터를 관리합니다. 이 영역은 프로그램의 모든 영역에서 공유합니다.
- 클래스 정보 : 클래스의 실행 코드, 필드, 메서드와 생성자 코드 등 모든 실행 코드가 존재합니다.
- static 영역 : static 변수들을 보관합니다.
- 런타임 상수 풀 : 프로그램을 실행하는데 필요한 공통 리터럴 상수를 보관합니다. 예를 들어 "hello" 라는 리터럴 문자가 있으면 이런 문자를 공통으로 묶어서 관리합니다.
자바에서 100개의 인스턴스를 생성하면, 힙 메모리에 100개의 인스턴스가 생성됩니다. 각각의 인스턴스는 내부에 변수와 메서드를 가지게 되는데, 같은 클래스로부터 생성된 객체여도 인스턴스 내부의 변수 값은 다를 수 있지만 메서드는 공통된 코드를 공유합니다.
따라서 객체가 생성될 때 인스턴스 변수에는 메모리가 할당되지만, 메서드에 대한 새로운 메모리 할당은 없고 메서드 영역에서 공통으로 관리되고 실행이 됩니다.
✅ 스택 영역
자바 실행 시, 하나의 실행 스택이 생성됩니다. 각 스택 프레임은 지역 변수, 중간 연산 결과, 메서드 호출 정보 등을 포함하게 됩니다.
- 스택 프레임 : 스택 영역에 쌓이는 네모 박스가 하나의 스택 프레임입니다. 메서드를 호출할 때마다 하나의 스택 프레임이 쌓이고, 메서드가 종료되면 해당 스택 프레임이 제거됩니다.
스택 영역은 정확히는 각 쓰레드 별로 하나의 실행 스택이 생성됩니다. 따라서 쓰레드 수만큼 스택 영역이 생성됩니다.
😶 스택이란 ?
스택이란 FILO (First-In-Last-Out) 구조로, 가장 마지막에 들어온 것이 가장 먼저 꺼내지게 됩니다.
1 -> 2 -> 3 번의 순서로 넣게 되면 3 -> 2 -> 1 번의 순서로 꺼내지게 됩니다.
✅ 힙 영역
힙 영역은 객체 (인스턴스) 와 배열이 생성되는 영역입니다. 가비지 컬렉션(GC) 이 이루어지는 주요 영역이며, 더 이상 참조되지 않는 객체는 GC에 의해 제거됩니다.
✅ 스택 영역과 힙 영역 코드로 알아보기
- Data 클래스
package memory;
public class Data {
private int value;
public Data(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
- JavaMemoryMain2 클래스
package memory;
public class JavaMemoryMain2 {
public static void main(String[] args) {
System.out.println("main start");
method1();
System.out.println("main end");
}
static void method1() {
System.out.println("method1 start");
Data data1 = new Data(10);
method2(data1);
System.out.println("method1 end");
}
static void method2(Data data2) {
System.out.println("method2 start");
System.out.println("data.value=" + data2.getValue());
System.out.println("method2 end");
}
}
위의 코드가 있을 때 메서드는 main() -> method1() -> method2() 순서로 호출이 됩니다.
method1() 에서 Data 클래스의 인스턴스를 생성하고,
method1() 에서 method2() 를 호출할 때 매개변수에 Data 인스턴스의 참조값을 전달합니다.
메서드 실행 순서대로 차래로 아래부터 스택 영역에 main() -> method1() -> method2() 순서로 쌓이게 되고,
method1() 은 new Data(10) 을 사용해서 힙 영역에 Data 인스턴스를 생성하였습니다. 그리고 참조값을 data1 에 보관하였습니다.
method1() 은 method2() 를 호출하면서 Data data2 매개변수에 x001 의 참조값을 넘기게 되고,
method1() 에 있는 data1 과 method2() 에 있는 data2 는 같은 x001 인스턴스를 참조하게 됩니다.
method2()가 종료되면, 스택 프레임이 제거되면서 data2 가 제거됩니다.
같은 방식으로 method1() 이 종료되면 해당 스택 프레임이 제거되면서 data1 도 함께 제거됩니다.
method1() 메서드가 종료되면, 힙 영역에 있는 Data 인스턴스를 참조하는 곳이 더 이상 없기 때문에 프로그램에서 사용하지 않는 객체가 되게 됩니다.
이런 객체는 메모리만 차지하게 되므로 GC(가비지 컬렉션) 는 참조가 모두 사라진 인스턴스를 찾아서 메모리에서 제거합니다.
힙 영역 외부가 아닌, 힙 영역 안에서만 인스턴스끼리 서로 참조하는 경우에도 GC 의 대상이 됩니다.
지역 변수는 스택 영역에, 객체(인스턴스)는 힙 영역에 관리됩니다. 메서드 영역이 관리하는 변수 또한 존재합니다.
static 키워드와 관련된 메서드 영역이 관리하는 변수는 다음 포스팅에서 하도록 하겠습니다 :)
🔍 참고글
인프런 [김영한의 실전 자바 - 기본편] 섹션 8. 자바 메모리 구조와 static 강의를 참고하여 작성했습니다.
'자바' 카테고리의 다른 글
[JAVA] ArrayList 자주 사용하는 메소드 (List/LinkedList) (0) | 2024.10.06 |
---|---|
[JAVA] 컬렉션 - List 정리 (ArrayList, LinkedList) (3) | 2024.10.06 |
[Intellij] 인텔리제이 자주 사용하는 단축키 모음 (윈도우) (3) | 2024.09.08 |
[JAVA] StringBuilder 사용법과 메소드 총정리 (3) | 2024.09.08 |
[JAVA] String이란? (String이 불변 객체인 이유 / String 메소드 정리) (2) | 2024.09.06 |