자바(JAVA)를 사용하는 입장에서 알아야 할 메모리 구조 및 특징
JVM(자바 가상 머신)은 OS로부터 메모리를 할당받고, 그 메모리를 용도에 따라서 여러 영역으로 나누어 관리를 한다.
각 변수의 생성시기
클래스변수 : 클래스가 메모리에 올라갈 때
인스턴스변수 : 인스턴스가 생성되었을 때
지역변수 / 매개변수 : 해당 메서드가 수행되었을 때( 메서드 수행이 끝나면 소멸됨 )
>> 클래스가 메모리에 올라가는 거랑 , 인스턴스가 생성되는거는 구분된다
JVM의 메모리 공간(Runtime Data Area)은 크게
Method(Static) 영역, Stack 영역, Heap 영역으로 구분된다

| 모든 쓰레드(Thread)가 공유하는 영역 | Method Area, Heap Area |
| 각 쓰레드 별로 생성되는 영역 | 나머지 Stack Area, PC Register, Native Method Stack |
힙 과 메서드 공간에는 어디서든지 접근이 가능하지만, 스택 메모리는 다른 스레드가 접근할 수 없다.

Method(Static) 영역
JVM이 시작될 때 생성되서, 프로그램이 종료 될 때까지 메모리에 남아있다.
바이트 코드(.class)를 처음 메모리 공간에 올릴 때 초기화되는 대상을 저장하기 위한 메모리 공간이다.
Method(Static) 영역에 있는 것은 어느곳에서나 접근 가능
그래서 static 메모리에 있는 데이터들은 프로그램이 종료될 때까지 어디서든 사용이 가능하다.
그러나 static 데이터를 무분별하게 많이 사용할 경우 메모리 부족 현상이 일어날수 있게 된다.

JVM이 읽어들인 클래스와 인터페이스, 클래스 변수(static)와 메소드 등을 저장하는 공간.
Runtime Constant Pool 이 포함됨
Runtime Constant Pool
Method 영역에 포함되지만 독자적 중요성을 띈다
클래스와 인터페이스의 메서드와 필드에 대한 모든 레퍼런스 저장
JVM은 런타임 상수 풀을 통해 해당 메서드나 필드의 실제 메모리상 주소를 찾아 참조함
Stack 영역
임시적으로 사용되는 변수나 정보들이 저장되는 영역이다.
자료구조Stack과 마찬가지로 LIFO( Last In First Out )구조
메소드가 호출될때 스택 영역에 스택 프레임이 생기고 메소드를 호출( 메서드 수행이 끝나면 프레임별로 삭제됨 )
(((
스택 프레임(stack frame)
하나의 메서드에 필요한 메모리 덩어리를 묶어서 스택 프레임(Stack Frame)이라고 한다
메서드의 매개변수, 지역변수, 리턴 값 및 연산 시 일어나는 값들을 임시로 저장
)))
( 지역변수, 매개변수 의 ) 기본 자료형에 해당되는 데이터 값이 저장

Heap 영역
JVM이 관리하는 프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당하여 사용하는 영역
Method Area에 저장된 클래스만이 인스턴스로 생성이 되어 적재된다
참조형(Reference Type) 데이터 타입을 갖는 인스턴스, 배열 등이 저장 되는 공간
( 단, Heap 영역에 있는 오브젝트들을 가리키는 레퍼런스 변수는 stack에 적재 )

Heap 영역은 Stack 영역과 다르게 보관되는 메모리가 호출이 끝나더라도 삭제되지 않고 유지된다.
그러다 어떤 참조 변수도 Heap 영역에 있는 인스턴스를 참조하지 않게 된다면, GC(가비지 컬렉터)에 의해 메모리에서 청소된다.
stack은 스레드 갯수마다 각각 생성되지만, heap은 몇개의 스레드가 존재하든 상관없이 단 하나의 heap 영역만 존재
가비지 컬렉터 (Garbage Collector ,GC)


JVM은 가비지 컬렉터(garbage collector)를 이용하여
Heap메모리 영역에서 더는 사용하지 않는 메모리( 힙영역에 참조되지않고 남아있는 인스턴스 )를 자동으로 회수해 준다.
Heap Area는 효율적인 GC를 위해 크게 2가지의 영역으로 나뉜다.

Young영역( Young Generation )
새롭게 생성된 객체가 할당(Allocation)되는 영역
대부분의 객체가 금방 Unreachable 상태가 되기 때문에, 많은 객체가 Young 영역에 생성되었다가 사라진다.
생긴지 얼마 안되는 객체가 저장되는 공간
Young영역에 대한 가비지 컬렉션을 Minor GC라고 부른다.
Old영역( Old Generation )
Young영역에서 Reachable 상태를 유지하여 살아남은 객체가 복사되는 영역
Young 영역보다 크게 할당되며, 영역의 크기가 큰 만큼 가비지는 적게 발생한다.
Old영역에 대한 가비지 컬렉션을 Major GC( Full GC )라고 부른다.
Permanent
클래스 로더에 의해 load되는 Class, Method 등에 대한 Meta 정보가 저장되는 영역이고 JVM에 의해 사용된다.
Java 7 까지는 힙 영역에 존재했지만 Java 8 버전 이후에는 Native Method Stack에 편입되게 된다.

Minor GC
Heap 영역에 객체가 생성되면 최초로 Eden 영역에 할당됨. 그리고 이 영역에 데이터가 어느정도 쌓이게 되면 참조정도에 따라 Survivor의 빈 공간으로 이동되거나 회수됨
Young Generation( Eden+Survivor ) 영역이 차게 되면 또 참조정도에 따라 Old영역으로 이동 되거나 회수됨
Major GC
Old영역에 할당된 메모리가 허용치를 넘게 되면, Old 영역에 있는 모든 객체들을 검사하여 참조되지 않는 객체들을 한꺼번에 삭제하는 GC가 실행됩니다.
시간이 오래 걸리는 작업이고 이 때 GC를 실행하는 쓰레드를 제외한 모든 스레드는 작업을 멈추게 됩니다. 이를 'Stop-the-World' 라 합니다.
이렇게 'Stop-the-World'가 발생하고 Old영역의 메모리를 회수하는 GC를 Major GC라고 합니다.
Stack영역과 Heap영역
Stack
기능수행 끝나면 자동으로 반환됨( 함수 수행되면 없어짐 )
Heap
CPU가 엄격하게 관리하지 않음
자동으로 관리되지 않음( 메모리 누수를 GC으로 해결 )
스택메모리의 생명주기는 매우 짧으며, 힙 메모리는 애플리케이션의 시작부터 끝까지 살아남는다.
자바 코드를 실행할때 따로 -Xms과 -Xmx 옵션을 사용하면 힙 메모리의 초기 사이즈와 최대 사이즈를 조절할 수 있다.
스택 메모리가 가득차면 자바에서는 java.lang.StackOverFlowError를 발생.
힙 메모리가 가득차면 java.lang.OutOfMemoryError : Java Heap Space 에러를 발생
스택 메모리 사이즈는 힙 메모리와 비교했을 때 매우 적다. 하지만 스택 메모리는 간단한 메모리 할당 방법(LIFO)를 사용하므로 힙 메모리보다 빠르다.
수동으로 GC(가비지 컬렉터)를 실행하기위해 System.gc() 라는 메소드를 사용할수 있지만, 함수 실제 실행은 보장되지는 않는다.
실제 코드와 JVM 메모리 공간들
main메소드에서, 메소드twice까지 실행됐을때의 모습( 아직 result2는 안생김 )

실행되어 볼일이 끝난 스택 프레임들은( plus, twice ) 제거 된다.
객체변수sub 가 메소드get()을 호출하면, 스택 영역에 새로운 스택 프레임get 이 생기고, 만든값을 반환한다.
할일을 마치 get스택 프레임은 스택 영역에서 제거되고
, main 스택 프레임에 result2 지역 변수가 추가된다.

main메서드의 끝인 닫는 중괄호 } 를 만나면 main스택프레임은 스택영역에서 제거된다
하지만 힙영역에는 여전히 Counter인스턴스가 남아있다
가비지 컬렉터( GC )가 힙영역에 참조되지않고 남아있는 인스턴스를 식별해서 청소한다

☕ JVM 내부 구조 & 메모리 영역 💯 총정리
저번 포스팅에서는 JRE / JDK / JVM에 대해서 간략하게 알아보는 시간을 가졌다면, 이번 포스팅에서는 JVM의 내부 구조에 대해 좀 더 자세하게 알아보도록 할 예정이다. JVM(자바 가상 머신)은 자바 언
inpa.tistory.com
☕ 그림으로 보는 자바 코드의 메모리 영역(스택 & 힙)
자바의 메모리 영역 이번 포스팅에선 자바(JAVA)를 사용하는 입장에서 알아야 할 메모리 구조 및 특징에 대해서 알아보려고 한다. 자바 프로그램이 실행되면 JVM(자바 가상 머신)은 OS로부터 메모
inpa.tistory.com
'Programing Language > JAVA' 카테고리의 다른 글
| Garbage Collection( GC, 가비지 컬렉션 ) (0) | 2024.04.03 |
|---|---|
| java.lang 패키지( import 없이 사용 ) (0) | 2024.03.21 |
| Memory Pool, Garbage Collection, 문자열 풀(String Pool) (1) | 2024.02.04 |
| Gradle (0) | 2023.11.27 |
| 클래스와 객체 01 (1) | 2023.11.22 |