2014-04-17 59 views
0

我有這樣的測試代碼:全局變量的內存分配在C++

#include <thread> 
#include <cstdint> 
#include <cstdlib> 

int32_t global_buffer[1024][1024][256]; 

int main() 
{ 
    std::this_thread::sleep_for(std::chrono::seconds(5)); 

    for (size_t i = 0; i < 1024; ++i) 
     for (size_t j = 0; j < 1024; ++j) 
     for (size_t k = 0; k < 256; ++k) 
       global_buffer[i][j][k] = rand(); 

    std::this_thread::sleep_for(std::chrono::seconds(5)); 

    int32_t* heap_buffer = new int32_t[1024 * 1024 * 256]; 
    for (size_t i = 0; i < 1024 * 1024 * 256; ++i) 
     heap_buffer[i] = rand(); 

    std::this_thread::sleep_for(std::chrono::seconds(5)); 

    delete[] heap_buffer; 

    std::this_thread::sleep_for(std::chrono::seconds(5)); 
} 

如果我運行的程序,用VS2013在32位編譯,在Windows 7上我有以下的內存行爲:

  1. 內存使用率是非常低的,幾KB第一約5秒時間
  2. 內存使用率增加,直到達到約1 GB
  3. 內存使用率停留約1 GB,持續5秒
  4. 內存使用跳到〜2 GB,並在那裏停留〜5秒
  5. 內存使用跳到〜1 GB

正如我不明白爲什麼1和2都發生我有幾個問題:

  1. 爲什麼程序不會以〜1 GB的內存使用量開始?
  2. 是否按需分配全局變量的內存?
  3. 這是一個VS/Windows特定的行爲或其他編譯器/ OS具有相同的行爲呢?
  4. 此行爲是否正確?性病說:

3.7.1靜態存儲

不具有動態存儲時間的所有變量,沒有 線程存儲時限,而不是本地有靜態存儲 時間。那些靜態存儲:這些實體的存儲應持續時間的程序

3.6.2非本地變量

  1. 有兩大類名爲非本地變量的初始化持續時間(3.7.1)和線程存儲持續時間(3.7.2)的持續時間爲 。具有靜態存儲持續時間的非局部變量 由於程序啓動而被初始化。具有線程存儲持續時間的非局部變量 被初始化爲線程執行的結果。在啓動的這些階段的每個階段中,初始化如下發生。

  2. 在進行任何其他初始化之前,應將靜態存儲持續時間(3.7.1)或線程存儲持續時間(3.7.2)的變量初始化爲零(8.5)。

+1

第一個和第二個點可能是因爲操作系統沒有一次映射所有內存,而是在需要時將其映射到進程的虛擬內存映射中。當您分配堆時,操作系統會立即將所有這些映射到進程中。 –

+0

@Joachim Pileborg即使在堆上,除非您訪問它,否則不會看到內存消耗。 –

回答

4

是對需求分配的全局變量的內存?

鏈接器只存儲在二進制代碼初始化的數據。運行時鏈接器在運行時分配具有靜態存儲持續時間的未初始化數據的空間,即使此時物理內存僅在您開始訪問該數據時才提交。有關更多詳細信息,請參閱data segment

+0

我爲我的global_buffer添加了初始化程序,現在可執行文件有〜1 GB – Felics

+0

@Felics這是當初始化程序非零時應該發生的情況,例如'int32_t global_buffer [1024] [1024] [256] = {1};'。 –

+0

是的,這就是我所做的。在運行時,我具有與問題中所述相同的行爲,即使我的可執行文件是〜1 GB – Felics