有沒有一種方法可以測量一個特定C++函數從程序堆棧中調用多少內存,直到它返回?有沒有一種方法可以測量特定函數從棧中消耗多少內存?
回答
假設有一個函數「testfunc」,我們希望找到多少stackspace這個機能的研究使用.....
#include <stdio.h>
#include <stddef.h>
ptrdiff_t testfunc (int arg1, int arg2, char *stackbase);
int main()
{
char *stackbase;
printf("\nThe amount of stack space used by \"testfunc\" is : %ul bytes\n",testfunc(10, 5, stackbase));
return 0;
}
ptrdiff_t testfunc (int arg1, int arg2, char *stackbase)
{
//.
//all function processing goes here
//.
//.
char temp;
return stackbase - &temp;
}
看到這裏 http://cboard.cprogramming.com/c-programming/90572-determine-functions-stack-size.html
顯然是沒有可移植的方法,因爲編譯器可以用函數做很多事情:從內聯到尾部優化。
但嚴格來說,沒有什麼可衡量的,因爲編譯器完全知道這個數字。那麼,除非你使用非常量大小的堆棧數組(在C99中允許,但不在C++中)。
一個找出愚蠢的辦法是看彙編代碼:
例如,該功能:
int f(int x, int y)
{
int z = x + y;
int h = z - 2;
return h;
}
被編譯在AMD64到:
f:
.LFB0:
.cfi_startproc
pushq %rbp ; save the pointer to the caller's frame
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp ; new frame starts from %rsp (current stack ptr)
; starting from this place look how %rbp is used
; the maximum offset is what you're looking for
.cfi_def_cfa_register 6
movl %edi, -20(%rbp)
movl %esi, -24(%rbp)
movl -20(%rbp), %edx
movl -24(%rbp), %eax
addl %edx, %eax
movl %eax, -8(%rbp)
movl -8(%rbp), %eax
subl $2, %eax
movl %eax, -4(%rbp)
movl -4(%rbp), %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
所以,在這個例子中,函數f將8字節的%rbp(舊幀指針)壓入堆棧,然後它使用%rbp-20,%rbp-24,%rbp-8和%rbp-4中的內存。最大偏移量是-24。 使用的總字節數是24個字節加上8個字節的%rbp和8個字節,在這裏對於返回指針是不可見的,如果我沒有遺忘任何東西,總共有40個字節。
我不確定這是不是你問的。
首先要看的是函數的C編譯器的彙編輸出,並計算所有調用,推送和堆棧幀。然後,您需要重複呼叫樹中的所有功能,查找最長的路徑以及它的總和。
如果你可以在調試器中運行該函數,只需在函數調用之前記下堆棧指針的值,直到你處於最深點並記下堆棧指針的值。這給你一個真實世界的號碼。
如果您可以重新編譯整個函數樹,請添加一個簡單的序言和結尾宏,以在全局變量中記錄堆棧指針的低水位標記。重新編譯整個項目並運行它。這給了你許多迭代的真實世界的數字。
如果您的函數調用第三方代碼,而您不知道該問題,則問題變得更加棘手。爲此,您可以簡單地將堆棧內存從當前堆棧點開始的40(或更多)字節處memset,調用該函數,然後查找自memset以來未改動的內存。
喜歡的東西(未經測試!):
編輯:哎呀,忘了堆棧增長了下來...
int StackTest() {
//marker is on the stack.
//"volatile" prevents it from optimized into a register.
volatile unsigned int marker= 0xDEADBEEF;
//The current stack pointer should be just below marker.
//I add 10*4 to move well below the current stack frame.
//If the program crashes at this point, try increasing
//the size of the buffer zone.
char *pStack= (char*)&marker[-10];
//I zap the unused stack space to a recognizable value.
//The fill bytes will be overwritten as the stack is used.
//The 4096 number may need to be adjusted; it needs to be
//larger than the stack bytes used but less than the total
//stack space remaining.
memset(pStack-4096,0xCD,4096);
//Now I call my target function.
function();
//Now I search for the first 8 fill bytes in a row.
//This number may need to be increased to rule out
//false positives, such as buffers (arrays) allocated
//on the stack but not completely filled, which leaves
//fill bytes untouched inside the buffer.
for(n1=0,matchCt=0;n1<4096 && matchCt<8;n1++) {
if(*(pStack-n1)==0xCD)
matchCt++;
else
matchCt= 0;
}
int stackUsed= n1-matchCt;
printf("Stack used: %d bytes.\n",stackUsed);
return(stackUsed);
}
請記住,硬件中斷還可以在隨機時間消耗堆棧。 編輯:這可能不是用戶進程的問題。
我不認爲你可能使用的任何操作系統都會在硬件中斷上消耗用戶堆棧。通用操作系統不是因爲兩個原因:1)如果用戶棧沒有足夠的空間,會發生可怕的事情。 2)除非中斷代碼對堆棧進行消毒(這是棘手和昂貴的),否則對於被中斷的進程可以使用敏感信息。 –
這是否也適用於「軟」中斷,例如定時器? – TeasingDart
當然。所有相同的論點適用。 –
- 1. 有沒有方法可以估計PHP數組將消耗多少內存?
- 2. 有沒有一種方法可以減少R中向量所需的內存?
- 3. 有沒有一種方法可以統計我在產量中有多少值?
- 4. 有什麼方法可以知道ElementTree DOM消耗多少內存?
- 5. 有沒有一種方法可以找出定義的方法在該方法外有多少參數? (PHP)
- 6. 有沒有一種方法可以從R內評估JavaScript?
- 7. 有沒有一種方法可以改變Javascript中的函數內的原型?
- 8. 有沒有一種方法可以測量頁面中Javascript的重量?
- 9. 有沒有一種方法可以識別什麼是緩存特定文件?
- 10. 有沒有一種方法可以計算特定用戶在關係型MySQL表中存儲的數據量
- 11. 有沒有一種方法可以定義一個全局變量,它可以從類方法訪問?
- 12. 有沒有一種方法可以讓ActionListener取消?
- 13. 有沒有一種方法可以測量WPF flowdoc中塊/節的高度?
- 14. 有沒有一種方法可以測量PHP中的分析時間?
- 15. 如何測量堆棧消耗的內存量?
- 16. 有沒有一種方法可以從Domino Designer中生成JavaDoc?
- 17. 有沒有一種方法可以預測.doc的大小?
- 18. 有什麼方法可以確定iSeries上的單個作業內存消耗?
- 19. 有沒有辦法測量一個shell命令使用了多少內存?
- 20. 有沒有一種方法可以將GC限制在JVM中特定的CPU%?
- 21. 有沒有一種方法可以從jar文件中運行clojure測試?
- 22. 在Java中,有沒有一種方法可以跟蹤堆或棧中創建的變量,方法或類?
- 23. 有沒有一種方法可以跟蹤API內的廣告?
- 24. 有沒有一種方法可以將fsolve矢量化?
- 25. 有一種方法可以測量java中的延遲網絡
- 26. 有沒有一種方法可以保存JavaScript DOM操作?
- 27. 有沒有一種方法可以運行多個IntentService?
- 28. 有沒有一種方法可以定義CSS中的顏色常量?
- 29. Matlab函數內存消耗
- 30. 有沒有一種方法可以按特定順序從數組中構建一個字符串?
相關? http://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-run-time-in-c –
@Ben:你爲什麼不自己檢查一下? –
@KarolyHorvath我做到了......它是...... –