2012-12-17 4 views
5

Java에서 (아마도 .net에서도) 원시 유형이 스택에 저장되며 참조 유형은 힙에 저장됩니다.참조 유형이 힙에 저장되는 이유는 무엇입니까?

제 질문은이 동작에 대한 proc/cons를 이해하지 못했습니다. 왜 우리는 스택 내에서 메모리 위치를 참조 할 수 없습니까? . 내가봤을 때 나는 옳은 설명을 찾을 수 없었다. (어쩌면 나는 그것을 빨아 먹는다.) 그러나 사람들이 통찰력을 제공 할 수 있다면 감사하겠다.

고마워.

+1

답변 : http://programmers.stackexchange.com/questions/142024/storage-of-value-types-and-reference-types-in-net – SpaceBison

+1

답장을 보내 주셔서 감사합니다. 지금 이것에 대한 비전. –

답변

2

메서드 반환시 스택 프레임이 파괴되므로 일반적으로 참조 형식을 스택에 저장할 수 없습니다. 메소드가 완료된 후에 역 참조 될 수 있도록 객체에 대한 참조를 저장하면 존재하지 않는 스택 위치를 역 참조하게됩니다.

핫 스폿 JVM은 이스케이프 분석을 수행 할 수 있으며 개체가 메서드 범위를 벗어날 가능성이 없다고 판단하면 실제로 스택에 할당합니다.

+0

그래서 스택 또는 힙에 데이터 조각을 저장하는 결정은 원시 또는 참조 형식이라는 사실과 아무 관련이 없다는 것을 암시합니까? 오히려 그것이 글로벌이든 로컬이든 관계가 있습니다. . 이것이 사실이라면 내 평생 거짓말이었습니다. Abc obj = new Abc()를 수행하면 Abc의 공간이 항상 힙에 들어갈 것이라고 생각했습니다. –

+0

원시적 인 경우에는 ** 반드시 스택에 ** 있으므로 "할 일이 없습니다"는 잘못되었습니다. 하지만 그렇습니다. JVM은 객체가 어디에 위치하는지에 대한 최종 판정을 내 렸습니다. 그래서 누군가가 그것에 대해 걱정하는 이유를 알지 못합니다. –

+2

'Abc'에 대한 공간과 'Abc'에 대한 참조 (포인터의 종류)를위한 공간을 구별해야합니다. 'Abc obj = new Abc()'에서'Abc' 객체를 저장하기 위해 힙에 메모리가 할당되고'obj' ** 참조를 위해 (작성된 코드 행은 메서드 본문의 일부라고 가정합니다) * 스택에 할당됩니다. –

8

저는 Java에서 (아마도 .net에서도) 원시 타입이 스택에 저장되는데, 여기서 참조 유형은 힙에 저장됩니다.

아뇨 하지 그 여부 프리미티브 또는 기준에 의존한다. 범위에 따라 스택 또는 힙 사용 여부에 따라 다릅니다. 로컬 변수는 스택에 할당되고 멤버 변수는 인스턴스가 생성 될 때 힙에 할당됩니다.

Do Java primitives go on the Stack or the Heap?

내 질문은 내가이 문제에 대한 PROC/단점을 이해하지 못하는 것이 었습니다 참조하십시오.

스택에 저장된 데이터는 메소드가 실행되는 동안에 만 지속됩니다. 메소드가 완료되면 스택에 할당 된 모든 데이터가 제거됩니다. 힙에 저장된 데이터는 폐기되지 않는 한 계속 유지됩니다 (Java의 경우 가비지 수집기에 의해 백그라운드에서 수행됨). C/C++와 같은 다른 언어에서는 명시 적으로 힙에 할당 된 데이터를 삭제하거나 해제해야합니다. 여기

String someMethod() { 
    int i = 0; 
    String result = "Hello"; 

    i = i + 5; 
    return result; 
} 

, 원시적 (int i) 스택에 생성되고 어떤 계산이 이루어집니다 :

는 다음과 같은 코드를 생각해 보자. 메서드가 끝나면 i에 더 이상 액세스 할 수 없으며 해당 값이 손실됩니다. result 참조에 대해서는 기본적으로 마찬가지입니다. 참조는 스택에 할당되지만 Object (이 경우 String 객체)는 힙에 할당됩니다. 참조를 반환 값으로 반환하면 참조하는 객체를 메서드 외부에서 계속 사용할 수 있습니다.

+0

당신이 말할 때까지 나는 당신의 설명에 따라 잘 진행되고있었습니다. 참조가 스택에 할당되었지만 객체 (이 경우 String 객체)가 힙에 할당되었습니다. 메서드가 시작되면 정수 "i"는 플랫폼에 따라 2 바이트를가집니다. 메소드가 완료되면 사라질 것입니다. 그러나 당신은 "결과"스택에 메모리뿐만 아니라 힙에 할당됩니다 말할까요? 또는 메서드 실행 중에 힙의 메모리 위치에 대한 포인터 만 존재 함을 의미합니까? –

+1

@MuhammadAhmedAbuTalib 정확히 말하면, 참조는 객체에 대한 포인터이며이 포인터는 스택에 할당되지만 객체 자체는 힙에 할당됩니다. 객체 자체는 다른 프리미티브와 다른 참조를 멤버로 포함 할 수 있습니다.이 경우 객체가 인스턴스화 될 때 힙에 할당됩니다. –

+0

감사합니다. andreas. –

0

스택 내에서 메모리 위치를 참조 할 수없는 이유는 무엇입니까?

이 결정은 메모리 아키텍처 결정으로 생각할 수 있습니다.

개념상 이상적으로 모든 데이터는 stack에서 검색 할 수 없습니다. 그러나 실제 환경에서는 프로그램의 어느 곳에서나 액세스 할 수있는 위치가 필요합니다. 따라서 스택 할 수 없습니다. 그들은 그것을 heap이라고지었습니다.

link은 더 많은 빛을 낼 수 있습니다.

1

여기서 참조 유형은 힙에 저장됩니다.

내가 정확히 그 부분에 의해 무슨 뜻인지,하지만 기억 나지 않는이 만 객체는 그 객체를 가리키는 참조는 스택에 아직 반면, heap에 저장됩니다. 아마 이것은 당신이 가진 의심이었습니다.

로컬 변수 만 stack에 저장되는 반면, 변수는 Heap에 저장됩니다. 예컨대 : 용

- 물론이 어떤 지역 범위에 정의되어있는 경우

String str = new String("Rohit"); // Local variable 

상기 경우에서, 참조 str, stack에 메모리를 할당한다. 그리고 Heap에 생성 된 새로운 문자열 개체를 가리 킵니다.

+0

답변을 주셔서 감사합니다. 간단하지만 설명이 좋습니다. 그러나 "왜"를 알고 싶었습니다. 힙을 왜 사용해야하는지, 왜 스택을 사용할 수 없습니까? 그것은 스택이 주요 "작업 영역"이기 때문에 코드가 실행될 때 상태가 바뀌므로 전역에 대한 자리 표시 자로 간주 될 수 없습니까? . –

+0

그리고 네가 내 의도를 정확히 추측 한 내 참조 유형은 내가 가진 혼란을 해결했다. 하지만이 비트는 그냥 남아 있습니다 –

+1

모든 메소드 호출은 스택에 저장됩니다. 이와 함께 우리가 전달하는 모든 매개 변수와 생성 된 로컬 변수가 저장됩니다. 이제 매개 변수와 로컬 변수를 저장하는 스택은 메소드가 실행되는 즉시 할당이 취소됩니다. 그리고 그들의 범위는 끝납니다. 따라서 더 나은 메모리 관리가 있습니다. 이제 우리가 객체에 관해서 이야기 할 때, 한 범위에서 생성 된 객체가 그 객체에 대한 참조를 보유하고 있다면 다른 범위에서 사용될 수 있다는 것을 기억하십시오. 따라서 스택에 저장해서는 안됩니다. –

관련 문제