스택에서 모든 것이 훨씬 더 효율적으로 이루어질 수 있다면 왜 힙이 필요한가요?


24

이것은 실제로 어제 우리가 오늘날 사용하는 응용 프로그램에 스택 힙이 모두 필요한 이유 에 대해 질문 한 것과 관련이 있습니다 (단순한 & 단일 표준으로 이동).

그러나 많은 응답은 힙을 할당 / 참조하려고 시도하는 것보다 수백 또는 수천 배 더 빠르기 때문에 스택을 대체 할 수 없음을 나타 냈습니다. 힙을 없애면 동적 스토리지 할당에 문제가 있지만 동적 메모리 할당을 처리 할 수 ​​있도록 스택을 개선하는 방법이 없습니까?


4
이전 질문에서 발췌 한 두 가지 발췌 : "가장 중요한 단점은 공간이 제한되어있어 큰 물체를 보관하거나 오래 사용하는 물체에 사용하려고하면 나쁜 생각입니다"와 "스택은 매우 효율적입니다" LIFO (최종순) 규칙을 준수하는 데이터를 관리하기위한 구조 "를 참조하십시오.
Cascabel

2
전제가 잘못 되었습니다. 스택에서 모든 것을 훨씬 더 효율적으로 수행 할 수있는 것은 아닙니다 . 무엇을하는 것은 것을 - 이것은 당신이받은 답변에 모순되지 않습니다 수 있습니다 훨씬 더 빨리가 할 수있는 스택에서 수행 될 수있다.
Ingo

... 하드웨어에 스택 또는 주소 기준 주소 지정이 있다고 가정합니다.
Ritch Melton

3
확신합니다. 나는 그렇게 말한다.
JeffO

답변:


25

스택의 문제점은 메모리가 스택 위에 있지 않으면 "사용 가능한"메모리를 사용할 수 없다는 것입니다. 예를 들어, 다양한 크기의 3 가지를 할당했다고 가정 해보십시오.

a = allocate(2000000); // 2000000 bytes
b = allocate(1);
c = allocate(5000000);

스택은 a하단, b중앙 및 c상단에 있습니다. 우리가 자유롭게하고 싶다면 이것은 문제가됩니다 b.

free(b); // b is not on top! We have to wait until c is freed!

해결 방법은 모든 데이터를 이후로 이동하고 이후 b에 오도록 변경하는 것입니다 a. 이것은 작동하지만이 경우 5000000 복사본 이 필요합니다 . 이것은 힙보다 훨씬 느립니다.

이것이 우리에게 힙이있는 이유입니다. 할당은 스택보다 느릴 수 있지만 ( O(log n)vs O(1)) 힙을 사용 O(log n)하면 스택과 비교하여 임의의 위치에서 메모리를 확보하는 것이 빠릅니다.O(n)


4
이와 관련하여 Facebook은 디스크를 제거하도록 요청할 때 디스크에서 컨텐츠를 제거하지 않고 단지 포인터를 제거합니다. 디스크 조각 모음을 시도하거나 디스크에서 동등한 간격을 찾으려고하는 오버 헤드는 데이터를 쓰는 속도로 너무 많은 시간이 걸리므로 디스크의 최고 워터 마크에 모든 것을 추가하기 만합니다.
Paul Tomblin

페이스 북의 디스크는 힙으로 볼 수 있습니다. 그리고 나는 그것들이 그 디스크에 대한 가비지 수집을 가지고 있다고 확신합니다.
deadalnix

2
@deadalnix 사실 이것은 대량의 메모리에 일반적으로 사용되는 힙 대신 거대한 스택을 사용하는 예입니다. Facebook은 특별한 경우입니다. 데이터가 제거되는 것보다 훨씬 빠르게 추가되어 할당 해제가 성장률에 큰 차이를 만들지 않습니다. 의도적으로 O (1) 할당을 얻기 위해 메모리 누수를 디자인에 포함시킬 수 있습니다.
Tom Clarkson

7
@PaulTomblin FB가 컨텐츠를 제거하지 않는 주된 이유는 그들이 이익을 위해 그것을 채굴 할 수 있도록하기 위해서입니다.
quant_dev

5
Facebook doesn't remove content from its disk when you ask it to remove it, it just removes the pointer to it-기본적으로 운영 체제에서 파일을 정상적으로 삭제할 때 발생합니다.
Robert Harvey

5

스택은 스레드 당, 힙은 프로세스 전체

100 개의 스레드가 처리중인 작업 항목을 큐에 넣은 경우 100 개의 스레드 중 하나가 볼 수 있도록 작업 항목을 정확히 어디에 배치해야합니까?

다른 유형의 메모리도 있습니다

예를 들어 메모리 매핑 된 파일, 공유 메모리, I / O 매핑 (커널 모드). 이러한 상황에서 효율성 논쟁은 일종의 약점입니다.


4

스택은 LIFO (last-in-first-out) 구조이며, 맨 위에는 참조 포인터가 유지됩니다 (일반적으로 하드웨어에서 지원됨). 이것을 말했듯이 힙 대신 스택에 할당하려고하는 것은이 스택의 맨 위에있는 모든 함수에서 로컬 변수 여야합니다. 따라서 스택에 대한 주된 이유는 모든 데이터 구조가 할당 될 때 main () 루틴이 프로그램이 사용하는 모든 데이터 구조 (프로그램의 전체 기간 동안 사용되도록 예정되어 있음)를 미리 할당해야하기 때문입니다. 함수 호출 내에서 함수 호출이 반환되고 프레임 또는 활성화 레코드가 스택에서 튀어 나오면 결국 함수 호출 내에서 제거됩니다.


3
FIFO가 아닌 LIFO.
Pubby

때때로 FILO라고도 함)
oenone

3

스택은 LIFO (Last in First out) 규칙을 따르는 메모리 할당에 효과적입니다. 즉, 메모리를 할당 한 정확한 역순으로 메모리를 해제합니다. LIFO는 매우 일반적이며 아마도 가장 일반적인 메모리 할당 패턴입니다. 그러나 이것이 유일한 패턴이거나 유일한 공통 패턴은 아닙니다. 광범위한 문제를 해결할 수있는 효율적인 프로그램을 작성하려면 더 복잡한 인프라를 의미하더라도 덜 일반적인 패턴을 허용해야합니다.

단락에 대한 모든 메타를 얻을 수 있다면 : 당신은 초보자이며, 초보자로서 단순함과 흑백 규칙을 중요하게 생각합니다. 그러나 초보자는 컴퓨터 프로그램이 수용해야하는 다양한 문제와 제약에 대한 정보 만 볼 수 있습니다. 귀하는 75 년 동안 활발한 발전을 거듭해 온 기술에 참여하고 있습니다. 사물이 왜 그런지 물어 보는 데는 아무런 문제가 없지만 대답은 일반적으로 "그렇습니다. 우리는 50 년 전에 간단하고 간단한 방법을 시도했지만 전체 수업에서 잘 작동하지 않는 것으로 나타났습니다. 문제를 해결해야하므로 더 복잡한 작업을 수행해야했습니다. " 기술이 발전함에 따라 단순성은 일반적으로 효율성과 유연성을 제공해야합니다.


0

다른 예를 들어, 폐쇄. 팝을 쌓으면 클로저의 활성화 기록을 잃을 수 있습니다. 따라서 익명 함수와 해당 데이터를 유지하려면 런타임 스택 이외의 곳에 저장해야합니다.


0

힙 스토리지를 할당하는 다른 많은 이유 중 하나입니다.

객체의 주소를 호출 프로그램으로 다시 전달하려면 스택 변수의 주소를 전달해서는 안됩니다. 스택 스토리지는 재사용되고 다음에 호출되는 함수에 의해 덮어 쓰기 될 수 있습니다. 후속 함수 호출로 덮어 쓰지 않도록 malloc ()을 사용하여 필요한 스토리지를 확보해야합니다.

프로그램에서 "returns ()"까지 존재하도록 보장 할 수 있으므로 스택 항목의 주소를 함수에서 호출하는 함수로 전달할 수 있습니다. 그러나 함수가 반환하자마자 모든 스택 스토리지가 사용됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.