- Local Variable
- 로컬 변수는 “스택 메모리” 영역에 저장합니다.
- 로컬 변수의 값은 각각 스레드의 “스택 프레임”에 할당됩니다.
- 메소드등이 실행을 하고 나면 로컬 변수의 메모리가 해제됩니다.
- Static Variable
- 정적 변수는 클래스 수준에서 선언 되는 변수입니다.
- 메소드 영역에 저장됩니다. 클래스 로딩 시에 메모리에 할당되며, 프로그램이 종료될 때까지 유지됩니다.
- Constant(static final).
- 변하지 않는 값을 의미하며, 컴파일 시에 값이결정됩니다.
- 메소드 영역의 “Runtime Constant Pool“이라는 영역에 저장됩니다.
- String Literal
- “Heap Memory” 영역에 저장됩니다.
- new 예약어를 쓰면 Heap 메모리에 할당 됩니다.
String str = “hello world”;
이렇게 쓰면 “String Constant Pool“ (Heap 메모리 내부에 존재) 에 저장됩니다.
- 자바에서는 문자열 리터럴이 동일한 경우 같은 문자열 인스턴스를 공유 합니다.
- 굳이 왜 두가지를 나눠서…?
- jdk 1.6 → 1.7로 업데이트 하면서 PermGen에서 힙영역으로 옮겼습니다.
- 이유는 Permgen의 고정 공간이 문제가 되었습니다. → OOM: PermGen
- Class의 메타데이터 (jdk 1.8 부터 permgen → metaspace로 변경 됬습니다.)
- “Metaspace” 영역에 저장됩니다.
- 클래스의 메타 데이터는 JVM 이 해당 클래스에 알아야하는 정보들을 포함합니다.
- Methoda metadata: method_info, bytecode, exception table, contstant, Annotations (jdk 1.5부터 도입된 것)
번외. Runtime Constant Pool 과 String Constant pool 사이
- jdk 1.6까지는 String constants pool도 같이 존재했습니다. 그러나 Permgen 이슈 때문에 1.7에서 힙영역으로 옮겼습니다.
- 마지막으로 Permgen(1.7)에서 Metaspace(1.8)로 변경하면서, Method 영역으로 옮겼습니다.
- 그래서 java 1.8 부터는 constant pool과 string constant pool은 다른 개념으로 분리가 됬습니다.
- 그러니까 뿌리는 같다..
번외. Metaspace(JDK1.8부터 등장)
- 클래스 메타 데이터를 저장하는 새로운 공간
- 자바 Heap과 연속된 공간이 아닙니다. → Not Contigiuous with the Java Heap
- Native Memory에 위치합니다.
- 메타스페이스가 쓸 수 있는 최대 메모리는 시스템 메모리의 가용 가능한 메모리입니다.
MaxMetaspaceSize
JVM 옵션으로 제한을 거는 방법도 있습니다.
MetaspaceSize
JVM 옵션도 추가 됬습니다.
- JVM Memory Management에서 관리하는 공간이 아닙니다.
- Metaspace 는 Class Metadata + Comrpessed Class Space(Default Size 1GB)로 이루어 져있습니다.
- Compressed Class Space는 메타데이터를 메모리에 효율적으로 저장하기 위해 사용되는 공간입니다.
- 클래스 구조 및 메타데이터를 압축하여 저장합니다.
- Metaspace의 할당되고 릴리즈 되는 시점
- Class가 로드 되고 JVM에 준비 될 때,클래스의 메타데이터 저장을 위해서 Metaspace에 의해 할당됩니다.
- 릴리즈는 클래스 로더가 Unload될 때만 일어난다.
- Metsapce 도 OutOfMemory(소위 OOM)이 납니다. 메모리 합계가 MaxMetaspaceSize를 넘거나 Compressed Class Space가 부족할때 가능합니다.
- jdk1.8 이전에는 메서드 영역이 perm 생성의 일부였지만 jdk1.8 이후에는 메서드 영역이 힙의 일부가 되었습니다.