01. JAVA 메모리 관리
JVM 메모리 구조 (주요)
1) 메소드 영역 : 클래스 정보, static 변수, 메서드 코드, 인터페이스 등
2) 힙 : 객체 배열, 참조형
3) 스택 : 메서드 호출 시 사용되는 지역변수, 매개변수, 리턴 값 등…
4) PC 레지스터 : 현재 실행중인 명령어의 주소를 저장하는 곳.
5) Native Method Stack : 자바가 아닌 네이티브 코드(C/C++) 실행
[예제 코드 1]
public class MyTest {
static int i = 1;
static double d = 1.2;
public static void main(String[] args) {
MyTest outer = new MyTest();
MyTest_inner inner = outer.new MyTest_inner();
int b1 = inner.div();
System.out.println(b1);
}
class MyTest_inner{
int div() {
return (int)(i/d);
}
}
}
[예제 코드 1 - JVM 메모리 맵 할당/해제 과정]
(1)
Method Area
+---------------------------------+
| Class: MyTest |
| static int i = 1 |
| static double d = 1.2 |
| static method: main() |
| Inner Class: MyTest_inner |
+---------------------------------+
(2)Stack
+-------------------------------+
| main() Stack Frame |
| args |
+-------------------------------+
(3)Heap
+-------------------------------+
| MyTest Object (outer) |
+-------------------------------+
Stack
+-------------------------------+
| main() Stack Frame |
| MyTest outer |
+-------------------------------+
(4)Heap
+-------------------------------+
| MyTest Object (outer) |
| -> MyTest_inner Object (inner)|
+-------------------------------+Stack
+-------------------------------+
| main() Stack Frame |
| MyTest outer |
| MyTest_inner inner |
+-------------------------------+
(5)Stack
+-------------------------------+
| div() Stack Frame |
| return 0 |
+-------------------------------+
| main() Stack Frame |
| MyTest outer |
| MyTest_inner inner |
| int b1 = 0 |
+-------------------------------+
(최종)Method Area
+---------------------------------+
| Class: MyTest |
| static int i = 1 |
| static double d = 1.2 |
| static method: main() |
| Inner Class: MyTest_inner |
+---------------------------------+
Heap → GC에 의해 자동 수거됨.
[예제 코드 2]
public class MyTest {
static int i = 1;
static double d = 1.2;
public static void main(String[] args) {
int a1 = sum();
int b1 = div();
MyTest01 mt = new MyTest01();
System.out.println(mt.getA());
System.out.println(a1 + "and" + b1);
}
static int sum(){
return (int)(i+d);
}
static int div(){
return (int)(i/d);
}
}
class MyTest01 {
private int a;
private int b;
public int getA(){
return a;
}
public int getB(){
return b;
}
}
[ 예제 코드 2 - JVM 메모리 맵 할당/해제 과정 ]
(1)
Method Area
+---------------------------------+
| `MyTest` 클래스 |
| static int i = 1 |
| `static double d = 1.2` |
| `static int sum()` |
| `static int div()` |
| `main()`|
| `MyTest01` 클래스 |
| `getA()` |
| `getB()` |
+---------------------------------+
Stack
+---------------------------------+
| main() 실행 |
| - a1 = 2 |
| - b1 = 0 |
| - mt (MyTest01 객체 주소) |
+---------------------------------+
(2) - 힙 영역에 객체 생성됨 stack 영역의 mt 변수가 객체의 주소값을 가지고 있음.
Heap
+---------------------------------+
| new MyTest01() 객체 생성 |
| a (초기값: 0) |
| b (초기값: 0) |
| - mt (MyTest01 객체 주소) |
+---------------------------------+
>> 디폴트 생성자로 초기화 되어 변수에 0이 자동 저장됨.
Stack
+---------------------------------+
| sum() 실행 | > return 2 (stack 제거)
| - mt (MyTest01 객체 주소) |
+---------------------------------+
(3)
Stack
+---------------------------------+
| div() 실행 | > return 0 (stack 제거)
| - mt (MyTest01 객체 주소) |
+---------------------------------+
(4)
Heap
+---------------------------------+
| getA() 실행 |
| a (초기값: 0) | return > 0
+---------------------------------+
Stack
+---------------------------------+
| println > mt.getA() |
| - mt (MyTest01 객체 주소) |
+---------------------------------+
(5)
main 종료 후 stack 해제 >> JVM 메모리 해제