.Net 서적이 스택 대 힙 메모리 할당에 대해 이야기하는 이유는 무엇입니까? 대해 이야기하고

모든 .net 책은 값 유형과 참조 유형에 대해 이야기하고 각 유형이 저장되는 위치 (힙 또는 스택)를 가리키게합니다 (종종 부정확 한). 일반적으로 처음 몇 장에 있으며 중요한 사실로 제시됩니다. 인증 시험 에도 적용되는 것 같습니다 . 스택 대 힙이 (초보자) .Net 개발자에게 중요한 이유는 무엇입니까? 당신은 물건을 할당하고 작동합니다, 그렇죠?



답변

이 정보가 중요하게 여겨지는 주된 이유는 전통 이라고 확신합니다 . 관리되지 않는 환경에서는 스택과 힙 간의 구별이 중요하므로 사용하는 메모리를 수동으로 할당하고 삭제해야합니다. 이제 가비지 콜렉션이 관리를 처리하므로 해당 비트를 무시합니다. 나는 어떤 유형의 메모리가 사용되는지 신경 쓰지 않아도된다는 메시지를 실제로 얻지 못했다고 생각합니다.

Fede가 지적한 바와 같이, 에릭 Lippert의이에 대해 할 말이 아주 흥미로운 일이 있습니다 http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx .

그 정보에 비추어 볼 때, 첫 번째 단락을 기본적으로 읽도록 조정할 수 있습니다. “사람들이이 정보를 포함하고 중요하다고 생각하는 이유는 과거에이 지식이 필요했던 부정확하거나 불완전한 정보 때문입니다.”

성능상의 이유로 여전히 중요하다고 생각하는 사람들을 위해 : 무언가를 측정하고 그것이 중요하다는 것을 알면 어떤 것을 힙에서 스택으로 옮기기 위해 어떤 조치를 취 하시겠습니까? 아마도 문제 영역의 성능을 개선하는 완전히 다른 방법을 찾을 것입니다.


답변

모든 .NET 서적은 값 유형과 참조 유형에 대해 이야기하고 각 유형이 저장되는 위치 (힙 또는 스택)를 가리키게합니다 (종종 잘못). 일반적으로 처음 몇 장에 있으며 중요한 사실로 제시됩니다.

나는 완전히 동의한다. 나는 이것을 항상 본다.

.NET 서적이 스택 대 힙 메모리 할당에 대해 이야기하는 이유는 무엇입니까?

그 이유 중 하나는 많은 사람들이 C 또는 C ++ 배경에서 C # (또는 다른 .NET 언어)을 사용했기 때문입니다. 이러한 언어는 스토리지 수명에 대한 규칙을 적용하지 않으므로 해당 규칙을 알고이를 따르기 위해 프로그램을 신중하게 구현해야합니다.

이제 이러한 규칙을 알고 C에서 규칙을 따를 때 “힙”과 “스택”을 이해 하지 않아도 됩니다. 그러나 데이터 구조의 작동 방식을 이해하면 규칙을 이해하고 따르는 것이 더 쉬운 경우가 많습니다.

초보자 용 책을 쓸 때 저자는 개념 배운 순서대로 설명하는 것이 당연 합니다. 반드시 사용자에게 맞는 순서는 아닙니다. 나는 최근 Scott Dorman의 C # 4 초급 책의 기술 편집자였으며, 내가 좋아했던 것 중 하나는 Scott이 메모리 관리에서 실제로 고급 주제를 시작하는 것이 아니라 주제에 대해 꽤 합리적인 순서를 선택했다는 것입니다.

그 이유 중 또 다른 부분은 MSDN 설명서의 일부 페이지가 스토리지 고려 사항을 강력하게 강조하기 때문입니다. 초기부터 아직도 남아있는 특히 오래된 MSDN 설명서. 그 문서의 대부분은 아직까지도 절제된 적이없는 미묘한 오류를 가지고 있으며, 특정 시점에 특정 청중을 위해 쓰여졌다는 것을 기억해야합니다.

스택 대 힙이 (초보자) .NET 개발자에게 중요한 이유는 무엇입니까?

제 생각에는 그렇지 않습니다. 훨씬 더 이해해야 할 것은 다음과 같습니다.

  • 참조 유형과 값 유형 사이의 복사 의미의 차이점은 무엇입니까?
  • “ref int x”매개 변수는 어떻게 작동합니까?
  • 값 유형을 변경할 수없는 이유는 무엇입니까?

등등.

당신은 물건을 할당하고 작동합니다, 그렇죠?

이상적입니다.

이제 중요한 상황이 있습니다. 가비지 콜렉션은 훌륭하고 상대적으로 저렴하지만 무료는 아닙니다. 작은 구조를 복사하는 것은 비교적 저렴하지만 무료는 아닙니다. 과도한 복사 비용과 수집 압력 비용의 균형을 유지해야하는 현실적인 성능 시나리오가 있습니다. 이 경우 모든 관련 메모리의 크기, 위치 및 실제 수명을 잘 이해하는 것이 매우 도움이됩니다.

마찬가지로, 스택에 무엇이 있고 힙에 무엇이 있는지, 가비지 콜렉터가 이동할 수있는 것을 알아야하는 현실적인 interop 시나리오가 있습니다. 이것이 C #에 “fixed”, “stackalloc”등과 같은 기능이있는 이유입니다.

그러나 이것들은 모두 고급 시나리오입니다. 이상적으로 초보자 프로그래머는 이러한 것들에 대해 걱정할 필요가 없습니다.


답변

너희들 모두 요점을 놓쳤다. 스택 / 힙 구분이 중요한 이유는 범위 때문입니다 .

struct S { ... }

void f() {
    var x = new S();
    ...
 }

일단 x가 범위를 벗어나, 생성 된 객체는 절대적으로되어 갔다 . 이는 힙이 아닌 스택에 할당되기 때문입니다. 그 사실을 바꿀 수있는 방법의 “…”부분에 들어갈 수있는 것은 없습니다. 특히, 할당이나 메소드 호출은 S 구조체의 복사본 만 만들 수 있었지만 계속 살아 남기 위해 새로운 참조를 만들지 않았습니다.

class C { ... }

void f() {
     var x = new C();
     ...
}

완전히 다른 이야기! x는 지금이기 때문에 , 그 객체 (즉, 객체 자체 가 아니라 그것의 사본) 아주 잘 이후에 계속 살 수 x가 범위를 벗어나. 실제로, x 가 유일한 참조 인 경우에만 계속 살아남지 못할 수 있습니다. “…”부분의 할당 또는 메소드 호출이 x 가 범위를 벗어날 때까지 “실제”인 다른 참조를 생성 한 경우 해당 객체는 계속 작동합니다.

그것은 매우 중요한 개념이며, “무엇을 왜”를 진정으로 이해하는 유일한 방법은 스택과 힙 할당의 차이점을 아는 것입니다.


답변

그들이 주제를 다루는 이유에 관해서는 @Kirk이 중요한 개념이며 이해해야한다는 데 동의합니다. 메커니즘을 더 잘 알수록 원활하게 작동하는 훌륭한 응용 프로그램을 만들 수 있습니다.

이제 Eric Lippert 는 대부분의 저자가 주제를 제대로 다루지 않는다는 데 동의하는 것 같습니다. 나는 그의 블로그를 읽고 그 아래에 무엇이 있는지에 대한 큰 이해를 얻는 것이 좋습니다.


답변

글쎄요, 그것이 관리되는 환경의 요점이라고 생각했습니다. 나는 심지어 언제든지 변경 될 수 있기 때문에 가정하지 말아야 할 기본 런타임의 구현 세부 사항을 이것을 호출하는 한까지 갔다.

.NET에 대해서는 잘 모르지만 실행하기 전에 JITted. 예를 들어, JIT는 이스케이프 분석을 수행 할 수 있으며 갑자기 스택에 또는 일부 레지스터에 객체가있는 것은 아닙니다. 당신은 이것을 알 수 없습니다.

필자는 저자가 그 책을 중요하게 여기거나 청중이 생각하기 때문에 일부 책에 단순히 해당 내용이 포함되어 있다고 가정합니다.

그럼에도 불구하고, 나는 “메모리 관리”라는 말보다 더 많은 것이 없다고 생각합니다. 그렇지 않으면 사람들은 잘못된 결론을 도출 할 수 있습니다.


답변

명시 적으로 관리하지 않아도 메모리 할당이 효율적으로 사용되도록 메모리 할당이 어떻게 작동하는지 이해해야합니다. 이것은 컴퓨터 과학의 거의 모든 추상화에 적용됩니다.


답변

차이를 만들 수있는 몇 가지 경우가있을 수 있습니다. 기본 스택 공간은 1meg이고 힙은 몇 기가입니다. 따라서 솔루션에 많은 수의 객체가 있으면 많은 힙 공간을 유지하면서 스택 공간이 부족할 수 있습니다.

그러나 대부분은 꽤 학문적입니다.