2011-02-11 4 views
6

가능한 중복 : 메모리 할당 관점에서 더 효율적입니다 무엇
C++ Which is faster: Stack allocation or Heap allocation더 효율적인 스택 메모리 또는 힙이란 무엇입니까?

- 스택 메모리 또는 힙 메모리? 그것은 무엇에 달려 있습니까?

분명히 동적 할당과 스택 할당의 오버 헤드가 있습니다. 힙을 사용하면 메모리를 할당하고 구조를 유지할 수있는 위치를 찾는 것이 포함됩니다. 스택에서 요소를 넣을 위치를 이미 알고 있으므로 간단합니다. 동적 할당을 허용하는 구조를 지원할 때 밀리 초 단위로 최악의 경우 오버 헤드가 무엇인지 이해하고 싶습니다.

+6

무엇 때문에 효율적입니까? – Anycorn

+7

달라질 수 있습니다 ..... –

+2

NARQ로 투표하려면 투표하십시오. –

답변

6

스택은 일반적으로 속도면에서 효율적이며 구현이 간단합니다.

나는 가능한 경우 스택 를 사용하는 것이 더 효율적입니다

말했다 소프트웨어 사이트에 조엘에서 마이클에 동의하는 경향이있다. 때때로 상대적으로 복잡 절차 입니다 메모리 무료 덩어리를 찾기 위해 무엇을

당신은 힙에서 할당

의 힙 관리자가 통과한다. 가끔은 을 조금보아야 만합니다. 이 맞는 크기입니다.

이것은 일반적으로 오버 헤드의 끔찍한 금액이 아닙니다. 그러나 이것은 보다 복잡한 작업인데 더 많은 것은 의 기능을 수행하는 것과는 다릅니다. 스택 에서 메모리를 사용하면 컴파일러는 에 즉시 스택의 메모리 덩어리를 할당 할 수 있습니다 (스택 ). 근본적으로 더 간단한 절차 인 입니다.

그러나, 스택의 크기는 제한 , 그래서 당신은 당신이보다 큰 뭔가 4K 정도처럼 무언가를 필요로하는 경우에, 당신은 항상 잡아해야 매우 큰 것을 위해 그것을 사용하지 말아야합니다 그 힙에서 대신.

스택을 사용의 또 다른 이점은 현재 함수가 종료, 당신은 그것을 직접 청소에 대해 걱정할 필요가 없습니다 때 자동 을 정리된다 입니다. 힙 할당에주의를 기울여서 을 정리해야합니다. 스마트 포인터를 사용하면 자동으로 힙을 삭제 할당이 많은 도움이 될 수 있습니다.

내가 프로그래머 2 개 정수와 에 대한 포인터를 필요로했기 때문에 그들은 단지 자동으로 필요한 가정에 대한 포인터를 볼 때 가 힙에서 할당과 같은 물건이 개 정수 을 수행하는 코드 볼 때 일종의 싫어 에 힙을 사용하십시오. 나는 이것을 경험이 적은 코더로 다소 덜 보입니다. - 이것은 이 스택을 사용해야하고 스택에 스택에 선언 된 정수 배열을 가지고 있어야합니다.

소프트웨어
사이트에 조엘에 정말 좋은 토론에서 인용 : 메모리의

stack versus heap: more efficiency?

4

일반적으로 힙 할당은 일반적으로 훨씬 더 복잡하지만 스택 포인터를 증가/감소시키는 것이기 때문에 스택에 할당/해제하는 것이 더 효율적입니다. 즉, 스택 공간이 대부분 시스템의 힙 공간보다 훨씬 제한되어 있으므로 (일반적으로 각 스레드가 별도의 스택을 가지고 있기 때문에 여러 스레드가 관련되어있을 때) 스택에 거대한 것을 넣는 것이 좋지 않습니다.

+0

여러 개의 스택을 통해 * 더 많은 스택 공간이있는 이유는 스택 공간이 "특히"제한된다는 의미입니까? –

+0

스레드 당 @Fred 스택 공간이 더 제한적입니다. 단일 스레드 시스템에서는 스택의 한쪽 끝에서 스택을 시작하고 다른 쪽 끝에서 힙을 "확장"할 수 있으므로 이론적으로 전체 가상 주소 공간을 스택에 사용할 수 있습니다 (힙을 사용하지 않은 경우). 스레드가 있으면 각 스레드마다 자체 스택이 필요합니다. 일반적으로 수행되는 방법은 각 스택에 대해 상대적으로 작은 주소 공간을 할당하는 것입니다. 각 슬라이스가 작을수록 더 많은 스레드가 있어야합니다. 이는 주소 공간이 훨씬 넓기 때문에 64 비트 시스템에서 문제가 될 가능성이 적습니다. –

+0

"플랫"주소 공간이있는 시스템에 있다고 가정하고 있다고 덧붙여 야합니다. 분할 포인터를 사용하는 경우 각 스레드의 스택을 다른 세그먼트에 배치 할 수 있습니다. 또한 일부 언어/런타임은 스택으로 멋진 작업을 수행하므로 확장이 가능합니다. 스택에 대한 포인터의 의미를 깨지 않고 C++ (또는 C)에서이 작업을 수행하는 방법을 알지 못하더라도 Go가 실제로 이것을 수행 할 수 있다고 생각합니다. –

0

스택은 훨씬 효율적이지만 크기는 제한적입니다. 나는 1MByte와 같다고 생각한다.

힙에 메모리를 할당 할 때 그림 1000을 염두에 두어야합니다. 힙에 할당하는 것은 스택보다 1000 배 느립니다.

+5

스택 크기는 플랫폼 및 응용 프로그램에 따라 다릅니다. 작업자 스레드를 만드는 경우 일반적으로 스택 크기를 정의 할 수도 있습니다. 확실히 "1MB"와 같은 마법 번호는 없습니다. – EboMike

+0

1000의 요인은 어디서 오는가? – Leonid

+0

@ 레이 니드 : 나는 잘 모른다. 그것은 시스템에 따라 달라질 것이고, 솔직히 말해서, 나는 결코 그것을 타임 아웃하지 않았다. –

1

이 두 영역이 서로 다른 사용 사례에 최적화되어 있습니다.

스택은 개체가 FIFO 순서로 할당 해제되는 경우에 최적화됩니다. 즉, 최신 개체는 항상 이전 개체보다 먼저 할당됩니다. 이 때문에, 거대한 바이트 배열을 유지 한 다음 끝에 바이트를 전달하거나 취소하여 메모리를 신속하게 할당하고 할당을 취소 할 수 있습니다. 함수 호출을위한 지역 변수를 저장하는 데 필요한 메모리는 항상 이러한 방식으로 재사용되기 때문에 (함수는 항상 호출 된 역순으로 실행이 끝나기 때문에) 스택은 이러한 종류의 메모리를 할당하기에 좋은 장소입니다.

그러나 스택은 다른 종류의 할당을 수행하는 데 적합하지 않습니다. 가장 최근에 할당 된 블록이 아닌 스택에서 할당 된 메모리를 쉽게 할당 해제 할 수 없습니다. 스택에서 "간격"이 발생하고 바이트를 사용할 수있는 위치를 결정하는 논리가 복잡해지기 때문입니다. 이러한 종류의 할당의 경우 개체가 할당 된 시간부터 개체 수명을 확인할 수없는 경우 힙은 개체를 저장하기에 더 좋습니다. 힙을 구현하는 데는 여러 가지 방법이 있지만 대부분의 경우 적절한 크기의 메모리를 쉽게 찾을 수 있도록 할당 된 블록의 거대한 테이블 또는 연결된 목록을 클라이언트에 다시 저장하는 아이디어에 의존합니다. 메모리가 해제되면 테이블 또는 링크 된 목록에 다시 추가되며 다른 블록과 함께 블록을 압축하기 위해 다른 논리가 적용될 수 있습니다. 검색 시간의 오버 헤드로 인해 힙은 일반적으로 스택보다 훨씬 느립니다. 그러나 스택은 일반적으로 스택이 좋지 않은 패턴으로 할당을 할 수 있으므로 일반적으로 두 개가 모두 프로그램에 있습니다.

흥미롭게도 두 가지 중간에있는 메모리를 할당하는 다른 방법이 있습니다. 하나의 일반적인 할당 기법은 "arena"라고하는 무언가를 사용합니다. 스택에서와 같이 하나의 큰 메모리 덩어리가 힙에서 할당 된 다음 작은 블록으로 분할됩니다. 이것은 할당이 순차적이면 (예를 들어, 같은 길이의 모든 작은 객체를 할당하려고하는 경우) 할당 영역이 매우 빠르지 만 객체가 특정 함수 호출보다 오래 머무를 수 있다는 이점을 제공합니다 .다른 많은 접근법이 존재하며 이는 가능한 작은 샘플링 일 뿐이지 만 메모리 할당은 모두 단점에 관한 것임을 분명히해야합니다. 특정 요구에 맞는 할당자를 찾아야합니다.

관련 문제