У меня есть программа, которая в основном делает это:
Мой вопрос: почему потребление памяти выглядит так, как показано ниже, хотя в моем прикрепленном коде нет явных утечек памяти?
Вот исходный код программы, которая была запущена для получения изображения выше:
#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;
}
У меня также есть следующие наблюдения:
fread()
из утечка памяти исчезает. Это странно, так как я не размещаю ничего рядом с ним, что может вызвать утечку памяти …fseeko()
из), утечка памяти также устраняется. Это сверхъестественная часть.Дальнейшая информация…
fread()
— ничего необычного не дает.fseek
а также ftell
,setbuf(fileHandle, NULL)
,setvbuf(fileHandle, NULL, _IONBF, *any integer*)
,g++ test.cpp -o test
, Оба представляют такое поведение.Я думаю, что это связано с каким-то внутренним созданием кэша, пока он не заполнится целым файлом. Как это действительно работает за кулисами? Как я могу предотвратить это портативным способом?
Я думаю, что это скорее проблема ОС (или даже проблема отчетности об использовании ресурсов ОС), чем проблема вашей программы. Конечно, он использует только 5 МБ памяти: 1 МБ для себя (библиотеки, стек и т. Д.) И 4 МБ для буфера. Всякий раз, когда вы выполняете fread (), ОС, кажется, «привязывает» часть файла к вашему процессу и, кажется, выпускает его не с той же скоростью. Поскольку использование памяти на вашем компьютере низкое, это не проблема: ОС просто сохраняет уже прочитанные данные «зависшими» дольше, чем необходимо, возможно, предполагая, что ваше приложение может прочитать их снова, в ближайшее время, а затем не Я должен сделать это снова.
Если бы нагрузка на память была выше, то операционная система, скорее всего, быстрее отсоединит память, так что скачок в истории использования памяти будет меньше.
У меня была точно такая же проблема, хотя в Java, но это не имеет значения в этом контексте. Я решил это, читая намного большие куски за раз. Я также читал фрагменты размером 4 Мб, но когда я увеличил их до 100-200 Мб, проблема ушла. Возможно, это сделает это и для вас. Я на Windows 7.