정적 메서드와 정적 변수는 Java에서 어디에 저장됩니까?


115

예를 들면 :

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, 힙 또는 스택 메모리에 어디에 저장됩니까? 어떻게 저장됩니까?


2
매우 유용한 링크는 오라클의 공식 웹 사이트에서 쓰레기 수집을 이해하기 : oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/...
Arnav 조시

답변:


144

정적 메서드 (사실상 모든 메서드)와 정적 변수는 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의 변경 사항을 확인하지 않았으므로 위의 내용이 해당 버전에 대해 여전히 사실 이라고 생각 합니다. 하지만 여기서 확실하지 않습니다.


1
Ahh 당신은 정적 변수에 대해 확신합니까? AFAIK PermGen은 실제 값이 아닌 정의 만 저장합니다.
Amir Raminfar 2011

2
@Amir 저는 변수 자체가 permgen 공간에 저장되어 있다고 확신합니다. 참조 된 모든 객체는 힙에 할당 될 가능성이 높습니다. 이 몇 가지 정보를 추가 할 수 있습니다 stackoverflow.com/questions/3800444/...
토마스

1
아 예 변수 정의는 permgen에 저장됩니다. 그러나 값은 힙에 있습니다. 귀하의 답변은 값이 PermGen에도 저장된다는 것을 제안했습니다.
Amir Raminfar 2011

1
@Matthew 내 대답을 어떻게 이해합니까? A는 변수 가 참조하는 객체가 아닌 permgen 섹션 (기본 요소 / 참조)에 저장되어 있다고 말했습니다 . 변수 을 보는 방법에 따라 다릅니다 .
토마스

1
@Nav 힙의 모든 부분이 기본적으로 가비지 수집되는 것은 아니며 때로는 클래스이므로 클래스 로더에 여전히 참조가 있기 때문에 정적 변수를 수집 할 수 없습니다. 또한 가비지 수집기에 의존해서는 안됩니다. 이는 전적으로 JVM에 달려 있기 때문입니다 (실행시기와 수집 대상을 결정합니다. "지금 gc를 실행하고 싶습니다."와 같은 힌트 만 제공 할 수 있습니다.)) .
토마스

25

클래스 변수 (정적 변수)는 Class object해당 클래스와 관련된 일부로 저장됩니다 . 이 클래스 개체는 JVM에서만 만들 수 있으며에 저장됩니다 permanent generation.

또한 일부는 비 힙 영역에 저장되어 있다고 대답했습니다 Method Area..이 대답도 틀리지 않습니다. Permgen Area가 힙의 일부인지 여부는 논쟁의 여지가있는 주제입니다. 분명히 인식은 사람마다 다릅니다. 제 생각에는 JVM 인수에서 힙 공간과 permgen 공간을 다르게 제공합니다. 따라서 그것들을 다르게 취급하는 것은 좋은 가정입니다.

그것을 보는 또 다른 방법

메모리 풀은 런타임 동안 JVM 메모리 관리자에 의해 생성됩니다. 메모리 풀은 힙 또는 비힙 메모리에 속할 수 있습니다. 런타임 상수 풀은 클래스 파일에있는 constant_pool 테이블의 클래스 별 또는 인터페이스 별 런타임 표현입니다. 각 런타임 상수 풀은 JVM (Java Virtual Machine)의 메소드 영역에서 할당되며 정적 변수는이 메소드 영역에 저장됩니다. 또한이 힙이 아닌 것은 perm gen 영역에 불과하며 실제로 Method 영역은 perm gen의 일부입니다. ( Reference )

여기에 이미지 설명 입력


메서드 영역은 메모리의 PermGen 섹션의 하위 집합이 아닙니까? (메서드 (클래스) 영역과 함께 PermGen) JVM의 더 큰 힙 영역의 일부일 때 비힙 메모리의 일부로 메소드 영역을 표시 한 이유는 무엇입니까?
Kaveesh Kanwal

마지막 줄 읽기Also this non-heap is nothing but perm gen area.Actually Method area is part of perm gen.
Aniket Thakur

1
@AniketThakur 당신은 비 힙 메모리의 일부로 메소드 영역을 보여 주었지만 오라클 문서에 따르면 여기 docs.oracle.com/javase/specs/jvms/se7/html/… , 메소드 영역은 논리적으로 힙.
Karan

21

Java 8 이전 :

정적 변수는 permgen 공간 (메서드 영역이라고도 함)에 저장되었습니다.

PermGen Space는 Method Area라고도합니다.

PermGen 공간은 3 가지 물건을 저장하는 데 사용되었습니다.

  1. 클래스 수준 데이터 (메타 데이터)
  2. 인턴 문자열
  3. 정적 변수

Java 8 이상

정적 변수는 힙 자체에 저장됩니다. Java 8부터는 PermGen Space가 제거되고 이전 Permgen Space와 달리 더 이상 힙의 일부가 아닌 MetaSpace라는 새 공간이 도입되었습니다. Meta-Space는 네이티브 메모리 (OS가 자체 사용을 위해 특정 애플리케이션에 제공하는 메모리)에 존재하며 이제는 클래스 메타 데이터 만 저장합니다.

인턴 된 문자열과 정적 변수는 힙 자체로 이동됩니다.

공식 정보는 JEP 122 : 영구 Gen 공간 제거를 참조하십시오.


정적 변수> Java8에 대해 "힙 자체"라고 말하면 정확히 OldGen?
Ewoks

15

이것은 간단한 대답과 장황한 대답이있는 질문입니다.

간단한 대답은 힙입니다. 클래스 및 클래스에 적용되는 모든 데이터 (인스턴스 데이터 아님)는 힙의 영구 생성 섹션에 저장됩니다.

긴 대답은 이미 스택 오버플로에 있습니다.

JVM의 메모리 및 가비지 수집에 대한 철저한 설명과 이에 대해 더 간결하게 이야기 하는 답변이 있습니다.


3
확실한 것! 유용하다고 생각되면 그 사람들을 찬성하는 것을 잊지 마십시오.
Vasiliy Sharapov 2011

11

클래스 정의에서 참조하는 힙에 저장됩니다. 생각해 보면 범위가 없기 때문에 스택과 관련이 없습니다.


5

Thomas의 답변 외에도 정적 변수는 Method Area라는 비 힙 영역에 저장됩니다.


4

정적 변수는 클래스 수준 변수이므로 힙 메모리의 " 영구 생성 "을 저장합니다. 로 봐주세요 JVM의 자세한 내용은. 이것이 도움이되기를 바랍니다.


3

정적 변수는 힙에 저장됩니다.


7
정적 변수는 메모리의 PremGen 공간에 저장되며 값은 힙에 저장됩니다.
Akash5288 2014 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.