오늘은 자바의 메모리영역에 대해 포스팅을 진행하려고합니다.
아무래도 기초는 계속 상기시켜야하기 때문에 포스팅으로 남기려고합니다.
먼저 메모리에 대해 작성하기 전에 JVM이 뭔지 알아보겠습니다
JVM
Java Virtual Machine의 약자로 자바 가상 머신이라고 불립니다.
자바의 바이트 코드를 해석하고 실행하는 역할을합니다.
1. java 파일을 컴파일러를 통해 class파일로 변환
2. class파일을 JVM의 ClassLoader로 전달
3. ClassLoader에서 JVM런타임 영역으로 할당하여 메모리에 올린다.
이때 이 런타임 영역에서 Stack, Heap, Static같은 메모리가 사용이 됩니다.
자바를 실행하게 되면 OS로부터 메모리를 할당받아서 여러개의 영역으로 나누어 사용하게되는데요.
변수를 예시로 들겠습니다.
public class Person {
public static int age = 27; // 클래스 변수
int weight = 60; // 인스턴스 변수
public void walk(int km) { // 매개변수
int bag = 10; // 지역변수
System.out.println(km + "속도로 걷기 [가방 : " + bag + "]");
}
}
클래스 변수 - 클래스가 메모리에 올라가는 시점부터 WAS가 종료될때까지 메모리에 올라와있습니다. [Static]
인스턴스 변수 - 인스턴스가 생성될 때 메모리에 올라가고, 인스턴스가 소멸될때 사라집니다. [Heap]
지역 변수 - 메서드 내부에서 선언이될 때 메모리에 올라가고 메서드 블럭을 벗어날때 해제됩니다. (매개변수 포함) [Stack]
Static 영역 (Method Area)
JVM이 실행될 때 Class가 로딩되는 시점에 같이 생성됩니다.
이때 클래스의 정보나 생성자, 메서드, Static 인자 들을 저장합니다.
그래서 Static 영역에 있을 경우 JVM이 실행되는 동안 메모리에 올라와있기 때문에 어디서든 접근이 가능합니다.
Heap 영역
인스턴스가 생성될 때 사용되는 메모리영역입니다.
참조형 데이터 객체의 실제 데이터가 저장되는 공간입니다.
만약에 new Person() 과 같이 new 키워드로 객체가 생성될 때 Heap에 저장됩니다.
이때 Person p = new Person(); 이라고한다면
Stack - p(변수)
Heap - Person 객체
이런식으로 힙에는 실제 객체가 저장되고 스택에는 객체의 참조값이 저장됩니다.
Thread가 몇개든 간에 단 하나의 영역만 존재하게됩니다.
이러한 Heap영역의 데이터는 가비지 컬렉터가 관리하면서 인스턴스가 소멸될 때 메모리에서 사라집니다.
Stack 영역
기본 자료형, 지역변수, 매개변수가 저장되는 공간입니다.
메서드가 호출될 때 메모리에 할당이 되고, 메서드 종료시 메모리에서 사라지게 됩니다.
쓰레드가 여러개의 경우 쓰레드마다 1개의 Stack 영역을 가지게 됩니다.
따라서 Thread간의 Stack영역이 다르므로 지역변수나 매개변수등은 Thread-safe합니다.
반대로 Static과 Heap영역은 Thread간 서로 공유합니다.
참고 블로그 - https://lucas-owner.tistory.com/38