예를 들면 :
class A {
static int i=0;
static int j;
static void method() {
// static k=0; can't use static for local variables only final is permitted
// static int L;
}
}
이러한 변수는 Java, 힙 또는 스택 메모리에 어디에 저장됩니까? 어떻게 저장됩니까?
답변
정적 메서드 (사실상 모든 메서드)와 정적 변수는 PermGen
리플렉션 데이터 (인스턴스 관련 데이터가 아닌 클래스 관련 데이터)의 일부이기 때문에 힙 섹션에 저장됩니다 .
설명을위한 업데이트 :
PermGen 공간에는 변수와 해당 기술 값 (프리미티브 또는 참조) 만 저장됩니다.
정적 변수가 객체에 대한 참조 인 경우 객체 자체는 힙의 일반 섹션 (젊음 / 오래된 세대 또는 생존자 공간)에 저장됩니다. 이러한 객체 (클래스 등과 같은 내부 객체가 아닌 경우 )는 PermGen 공간에 저장 .
예:
static int i = 1; //the value 1 is stored in the PermGen section
static Object o = new SomeObject(); //the reference(pointer/memory address) is stored in the PermGen section, the object itself is not.
가비지 컬렉션에 대한 한마디 :
마십시오 하지 의지finalize()
실행이 보장 . 객체가 가비지 수집에 적합하더라도 가비지 수집기를 실행할시기와 수집 대상을 결정하는 것은 전적으로 JVM의 몫입니다.
물론 정적 변수를 null로 설정하여 힙의 개체에 대한 참조를 제거 할 수 있지만 그렇다고 가비지 수집기 가이를 수집 한다는 의미 는 아닙니다 (더 이상 참조가 없더라도).
또한 finalize()
한 번만 실행되므로 예외가 발생하지 않거나 개체가 수집되지 않도록해야합니다. 일부 예외를 통해 종료를 중지 finalize()
하면 동일한 개체에서 두 번째로 호출되지 않습니다.
마지막 참고 : 코드, 런타임 데이터 등이 저장되는 방법은 사용되는 JVM에 따라 다릅니다. 즉, HotSpot은 JRockit과 다르게 수행 할 수 있으며 동일한 JVM의 버전 간에도 다를 수 있습니다. 위의 내용은 Java 5 및 6 용 HotSpot을 기반으로합니다 (기본적으로 동일 함). 답변 당시 대부분의 사람들이 해당 JVM을 사용했다고 말하고 있기 때문입니다. Java 8에서 메모리 모델의 주요 변경 사항으로 인해 위의 설명은 Java 8 HotSpot에 대해 사실이 아닐 수 있으며 Java 7 HotSpot의 변경 사항을 확인하지 않았으므로 위의 내용이 해당 버전에 대해 여전히 사실 이라고 생각 합니다. 하지만 여기서 확실하지 않습니다.
답변
클래스 변수 (정적 변수)는 Class object
해당 클래스와 관련된 일부로 저장됩니다 . 이 클래스 개체는 JVM에서만 만들 수 있으며에 저장됩니다 permanent generation
.
또한 일부는 비 힙 영역에 저장되어 있다고 대답했습니다 Method Area.
.이 대답도 틀리지 않습니다. Permgen Area가 힙의 일부인지 여부는 논쟁의 여지가있는 주제입니다. 분명히 인식은 사람마다 다릅니다. 제 생각에는 JVM 인수에서 힙 공간과 permgen 공간을 다르게 제공합니다. 따라서 그것들을 다르게 취급하는 것은 좋은 가정입니다.
그것을 보는 또 다른 방법
메모리 풀은 런타임 동안 JVM 메모리 관리자에 의해 생성됩니다. 메모리 풀은 힙 또는 비힙 메모리에 속할 수 있습니다. 런타임 상수 풀은 클래스 파일에있는 constant_pool 테이블의 클래스 별 또는 인터페이스 별 런타임 표현입니다. 각 런타임 상수 풀은 JVM (Java Virtual Machine)의 메소드 영역에서 할당되며 정적 변수는이 메소드 영역에 저장됩니다. 또한이 힙이 아닌 것은 perm gen 영역에 불과하며 실제로 Method 영역은 perm gen의 일부입니다. ( Reference )
답변
Java 8 이전 :
정적 변수는 permgen 공간 (메서드 영역이라고도 함)에 저장되었습니다.
PermGen Space는 Method Area라고도합니다.
PermGen 공간은 3 가지 물건을 저장하는 데 사용되었습니다.
- 클래스 수준 데이터 (메타 데이터)
- 인턴 문자열
- 정적 변수
Java 8 이상
정적 변수는 힙 자체에 저장됩니다. Java 8부터는 PermGen Space가 제거되고 이전 Permgen Space와 달리 더 이상 힙의 일부가 아닌 MetaSpace라는 새 공간이 도입되었습니다. Meta-Space는 네이티브 메모리 (OS가 자체 사용을 위해 특정 애플리케이션에 제공하는 메모리)에 존재하며 이제는 클래스 메타 데이터 만 저장합니다.
인턴 된 문자열과 정적 변수는 힙 자체로 이동됩니다.
공식 정보는 JEP 122 : 영구 Gen 공간 제거를 참조하십시오.
답변
이것은 간단한 대답과 장황한 대답이있는 질문입니다.
간단한 대답은 힙입니다. 클래스 및 클래스에 적용되는 모든 데이터 (인스턴스 데이터 아님)는 힙의 영구 생성 섹션에 저장됩니다.
긴 대답은 이미 스택 오버플로에 있습니다.
JVM의 메모리 및 가비지 수집에 대한 철저한 설명과 이에 대해 더 간결하게 이야기 하는 답변이 있습니다.
답변
클래스 정의에서 참조하는 힙에 저장됩니다. 생각해 보면 범위가 없기 때문에 스택과 관련이 없습니다.
답변
Thomas의 답변 외에도 정적 변수는 Method Area라는 비 힙 영역에 저장됩니다.