然而對於軟件工程師來說,有些性能問題是不可原諒的,無論它們屬於10%或是90%,都是“必須”改進的。這裡就講講其中的一個問題:用heap還是用stack的問題。
Java, C#,和JavaScript的程序員一般都不用管自己創建的object是在heap裡還是在stack裡,因為對於這些語言,object 只能“生活在”heap裡。這無疑對於程序員來說簡單了許多。但是對於C++程序員來說,你可以選擇三處來創建object:
Object 因該生活在哪裡?這個問題必須由應用的屬性來決定,有時是沒有選擇的,比如對於動態產生的全程變量,只有活在heap裡,別無它途。
然而,一旦我們有選擇,比如臨時的,作為復雜數據的載體的object,答案是清楚的:應該首選stack. 比如下面簡單的例子:
// heap vs stack test
double HeapVsStack(bool heap, int loop, int &result)
{
if (heap)
{
clock_t begin = clock();
for(int i = 0; i < loop; ++i)
{
intPair *p = new intPair(1,2);
result += p->ip1 + p->ip2;
delete p;
}
clock_t end = clock();
return double(end - begin) / CLOCKS_PER_SEC;
}
else
{
clock_t begin = clock();
for(int i = 0; i < loop; ++i)
{
intPair p = intPair(1,2);
result += p.ip1 + p.ip2;
}
clock_t end = clock();
return double(end - begin) / CLOCKS_PER_SEC;
}
}
程序中黑體放大的部分是要測量的“應用邏輯”,上方在heap中創建了一個intPair,用完後delete掉。下方在stack裡定義一個同樣的auto變量,用完後無須care.
對這個程序作下列簡單測試調用:
int result = 0;
printf("Heap time: %f \n", HeapVsStack(true, 100000, result));
printf("Stack time: %f \n", HeapVsStack(false, 100000, result));
我不得不調用100000次,原因是它們的耗時差別實在太大了:stack 的用例不到10000次以上都顯示0ms.
測試結果,heap用了300ms, stack用了5ms, 相差60倍。
結論:
1) 如果應用邏輯容許,用 stack-based auto 變量,千萬不用 heap 變量.
2) 如果需要大量用heap,建議用std::vector來當作自己的 heap 簡單管理器用。避免直接地,大量地用heap來創建 ad-hoc object.
3) 有些臨時計算用的class可以考慮禁止在heap中生成,見http://stackoverflow.com/questions/1941517/explicitly-disallow-heap-allocation-in-c 文章。
2014-8-23 西雅圖
引用:www.blogjava.net/...9.aspx
上午看某文章時候涉及緩沖區溢出的問題,談到C的棧和堆,有所不懂於是baidu了一下發現論壇上的解釋都較為凌亂,google一下後發現國外大學的Lecture Notes 中有不少的說明,下面簡單的摘錄三段,一是c中的,二是對於java的,三是從os角度看的。
Stack vs Heap Allocation
How the memory of the computer is organized for a running program? When a program is loaded into memory, it is organized into three areas of memory, called segments: the text segment, stack segment, and heap segment. The text segment (sometimes also called the code segment) is where the compiled code of the program itself resides. This is the machine language representation of the program steps to be carried out, including all functions making up the program, both user defined and system.
The remaining two areas of system memory is where storage may be allocated by the compiler for data storage. The stack is where memory is allocated for automatic variables within functions. A stack is a Last In First Out (LIFO) storage device where new storage is allocated and deallocated at only one ``end'', called the Top of the stack. This can be seen in Figure 14.13.
figure14.13.gif
When a program begins executing in the function main(), space is allocated on the stack for all variables declared within main(), as seen in Figure 14.13(a). If main() calls a function, func1(), additional storage is allocated for the variables in func1() at the top of the stack as ......余下全文>>
堆是動態申請的,比如malloc或new,而棧是靜態的。
而且申請的存儲空間的位置不同。