簡體   English   中英

以相反順序讀取fread()文件會導致內存泄漏?

[英]Reading file with fread() in reverse order causes memory leak?

我有一個基本上這樣做的程序:

  1. 打開一些二進制文件
  2. 向后讀取文件(向后,我的意思是它開始在EOF附近,並在文件開頭讀取,即從右向左讀取文件),使用4MB塊
  3. 關閉文件

我的問題是:為什么內存消耗看起來如下,即使我附加的代碼中沒有明顯的內存泄漏?

程序執行期間的內存消耗

以下是為獲取上述圖像而運行的程序源:

#include <stdio.h>
#include <string.h>

int main(void)
{
    //allocate stuff
    const int bufferSize = 4*1024*1024;
    FILE *fileHandle = fopen("./input.txt", "rb");
    if (!fileHandle)
    {
        fprintf(stderr, "No file for you\n");
        return 1;
    }
    unsigned char *buffer = new unsigned char[bufferSize];
    if (!buffer)
    {
        fprintf(stderr, "No buffer for you\n");
        return 1;
    }

    //get file size. file can be BIG, hence the fseeko() and ftello()
    //instead of fseek() and ftell().
    fseeko(fileHandle, 0, SEEK_END);
    off_t totalSize = ftello(fileHandle);
    fseeko(fileHandle, 0, SEEK_SET);

    //read the file... in reverse order. This is important.
    for (off_t pos = totalSize - bufferSize, j = 0;
        pos >= 0;
        pos -= bufferSize, j ++)
    {
        if (j % 10 == 0)
        {
            fprintf(stderr,
                "reading like crazy: %lld / %lld\n",
                pos, totalSize);
        }

        /*
         * below is the heart of the problem. see notes below
         */
        //seek to desired position
        fseeko(fileHandle, pos, SEEK_SET);
        //read the chunk
        fread(buffer, sizeof(unsigned char), bufferSize, fileHandle);
    }

    fclose(fileHandle);
    delete []buffer;
}

我還有以下觀察:

  1. 即使RAM使用量增加1GB,整個程序也只使用5MB完全執行。
  2. 評論對fread()調用會使內存泄漏消失 這很奇怪,因為我沒有在它附近分配任何東西,這可能會引發內存泄漏......
  3. 此外,正常讀取文件而不是向后讀取(=注釋調用fseeko() ),也會使內存泄漏消失 這是極其奇怪的部分

更多的信息.​​..

  1. 以下沒有幫助:
    1. 檢查fread()結果 - 不會產生任何異常。
    2. 切換到正常,32位fseekftell
    3. 做像setbuf(fileHandle, NULL)類的東西。
    4. setvbuf(fileHandle, NULL, _IONBF, *any integer*)東西setvbuf(fileHandle, NULL, _IONBF, *any integer*)
  2. 通過cygwin和mingw在Windows 7上用g ++ 4.5.3編譯; 沒有任何優化,只需g++ test.cpp -o test 兩者都存在這種行為。
  3. 測試中使用的文件長度為4GB,充滿了零。
  4. 可以通過某種臨時I / O掛斷來解釋圖表中間的奇怪停頓,與此問題無關。
  5. 最后,如果我在無限循環中包裝讀數...內存使用在第一次迭代后停止增加。

我認為它與某種內部緩存構建有關,直到它填滿整個文件。 幕后真的如何運作? 如何以便攜方式防止這種情況?

我認為,這是一個操作系統問題(甚至是操作系統資源使用報告問題),而不是程序問題。 當然,它只使用5 MB內存:自身為1 MB(libs,堆棧等),緩沖區為4 MB。 每當你執行fread()時,操作系統似乎將文件的一部分“綁定”到你的進程,並且似乎不會以相同的速度釋放它。 由於機器上的內存使用率很低,這不是問題:操作系統只是讓已經讀取的數據“閑置”超過必要的時間,可能假設您的應用程序可能很快再次讀取它,然后它就不會必須再次做那個綁定。

如果內存壓力較高,則操作系統很可能會更快地解除內存綁定,因此內存使用歷史記錄的跳躍會更小。

我有完全相同的問題,雖然在Java中,但在這種情況下無關緊要。 我通過一次讀取更大的塊來解決它。 我還讀了4Mb大小的塊,但是當我把它增加到100-200 Mb時,問題就消失了。 也許它也會為你做到這一點。 我在Windows 7上。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM