1. 程式人生 > >什麼是堆,棧,記憶體洩漏和記憶體溢位?

什麼是堆,棧,記憶體洩漏和記憶體溢位?

       一個執行緒的開銷包括:
      核心模式下的開銷(核心
堆疊,物件管理所需記憶體)
      使用者模式下的開銷(執行緒區域性儲存、執行緒環境塊、堆疊、CRT、MFC、COM等等等等)

      通常,執行緒數目的瓶頸在於執行緒自己的堆疊。Visual C++編譯器預設設定是每個執行緒的堆疊
大小是1MB。當然,如果你在建立執行緒時指定較小的堆疊大小,你應該可以建立較多的執行緒。

      但是建立大量執行緒不是一個好的設計。每個執行緒建立和銷燬的時候,Windows會呼叫已經載入的動態連結庫的DLLMain,傳遞DLL_THREAD_ATTACH和DLL_THREAD_DETACH作為引數,除非動態庫使用DisableThreadLibraryCalls禁用了這個通知。在建立大量執行緒的時候,這個開銷是很大的。對於你這樣的用後即棄的執行緒,你應該使用執行緒池。一個執行緒池示例可以在微軟知識庫找到。

     引數和區域性變數的函式都儲存線上程的堆疊。 如果宣告區域性變數具有大型值, 堆疊快速耗盡。 例如, 在以下程式碼示例函式要求堆疊來儲存陣列 1,200,000 個位元組。

void func(void)
   {
     int i[300000];
     // Use 300,000 integers multiplied by 4 bytes per integer to store the array.
     return;
   }

要避免使用堆疊, 使用動態分配記憶體。 例如, 在以下程式碼示例函式動態分配記憶體。
void func(void)
   {
     int *i

     i = new int[400000];
     // More code goes here.
     return;
   }
   在此程式碼示例, 記憶體儲存在堆疊代替。 因此, 函式不需要堆疊來儲存陣列 1,200,000 個位元組。
由此也解開了為什麼我在一個程序中建立大於2000個執行緒時導致程式異常退出,因為每個執行緒的預設堆
棧是1MB,2000*1MB = 2GB,my God!
可以在建立執行緒時指定執行緒堆疊大小,這樣就能建立更多的執行緒了!