C++ 以相反的顺序读取fread()文件会导致内存泄漏吗?
我有一个基本上做到这一点的程序:C++ 以相反的顺序读取fread()文件会导致内存泄漏吗?,c++,c,io,low-level,C++,C,Io,Low Level,我有一个基本上做到这一点的程序: 打开一些二进制文件 使用4MB数据块向后读取文件(所谓向后,我的意思是它在EOF附近开始,并在文件开始处结束读取,即“从右向左”读取文件) 关闭文件 我的问题是:为什么内存消耗如下所示,即使在我附加的代码中没有明显的内存泄漏 以下是为获得上述图像而运行的程序源: #包括 #包括 内部主(空) { //分配物品 const int bufferSize=4*1024*1024; FILE*fileHandle=fopen(“./input.txt”,“rb”);
#包括
#包括
内部主(空)
{
//分配物品
const int bufferSize=4*1024*1024;
FILE*fileHandle=fopen(“./input.txt”,“rb”);
如果(!fileHandle)
{
fprintf(stderr,“没有您需要的文件”);
返回1;
}
unsigned char*buffer=新的unsigned char[bufferSize];
如果(!缓冲区)
{
fprintf(stderr,“您没有缓冲区”\n);
返回1;
}
//获取文件大小。文件可能很大,因此使用fseeko()和ftello()
//而不是fseek()和ftell()。
fseeko(文件句柄,0,SEEK_END);
off_t totalSize=ftello(文件句柄);
fseeko(文件句柄,0,SEEK_集);
//以相反的顺序读取文件。这很重要。
对于(off_t pos=totalSize-bufferSize,j=0;
pos>=0;
pos-=缓冲区大小,j++)
{
如果(j%10==0)
{
fprintf(标准,
“疯狂阅读:%lld/%lld\n”,
pos,总尺寸);
}
/*
*下面是问题的核心。请参见下面的注释
*/
//寻找理想的位置
fseeko(文件句柄、位置、搜索集);
//读这段话
fread(buffer,sizeof(unsigned char),bufferSize,fileHandle);
}
fclose(文件句柄);
删除[]缓冲区;
}
我也有以下意见:
fread()
out可以消除内存泄漏。这很奇怪,因为我没有在它附近分配任何东西,这可能会触发内存泄漏fseeko()
out),也会消除内存泄漏。这是非常奇怪的部分fread()
-的结果不会产生任何异常fseek
和ftell
setbuf(fileHandle,NULL)
的操作setvbuf(fileHandle,NULL,_-IONBF,*任意整数*)
的操作g++test.cpp-o test
。两者都表现出这种行为我认为这与某种内部缓存的建立有关,直到它被整个文件填满。它在幕后到底是如何运作的?如何以可移植的方式防止这种情况发生???我认为,这与其说是程序的问题,不如说是操作系统问题(甚至是操作系统资源使用报告问题)。当然,它只使用5 MB内存:1 MB用于自身(libs、stack等),4 MB用于缓冲区。每当您执行fread()时,操作系统似乎会将文件的一部分“绑定”到您的进程,并且似乎会以不同的速度释放它。由于计算机上的内存使用率较低,这不是问题:操作系统只是将已经读取的数据“挂起”的时间比必要的时间长,可能是假设应用程序可能很快再次读取数据,然后就不必再次进行绑定
如果内存压力更大,操作系统很可能会更快地解除内存绑定,因此内存使用历史记录上的跳跃会更小。我也遇到了完全相同的问题,尽管是在Java中,但在这种情况下并不重要。我通过一次读更大的文章来解决这个问题。我也读4Mb大小的块,但当我把它增加到100-200MB时,问题就消失了。也许这对你也有好处。我使用的是Windows 7。您尝试过通过valgrind运行它吗?(或任何其他内存调试器)首先,这不好
const int bufferSize=4*1024*1024
。。。它应该是const int bufferSize=sizeof(int)*1024*1024
@jacobbollack:4*1024*1024部分只有4MB。它可以是任何内容,例如8KB。它与整数的大小无关…@Jocke:使用内存调试器可能是无用的-问题是,在我使用的任何资源监视器中,整个程序都使用5MB。我没有看到内存泄漏。在程序执行过程中,我看到大量内存使用,但这与内存泄漏完全不同。在我看来,向后读取文件是一项简单的任务。为什么操作系统(Windows7)会迭代地缓存整个4GB文件,直到内存耗尽,它不得不求助于页面文件,然后。。。?(它会这样做,取决于我的缓冲区大小…)你确定Win7正在忙着分页吗?或者,它只是忙于重新读取您的4G文件,而该文件(部分)由于笨拙而从文件缓存中抛出?因为您正在反向读取,读取文件的磁盘活动听起来可能与密集分页非常相似。磁盘活动本身不会污染RAM,是吗?在Win8上证实了同样的行为。谁说“RAM被污染了”?仅仅因为操作系统锁定了一个页面(并因此将其报告为“已使用”),并不意味着它是脏的。当我使用4MB缓冲区读取某些内容时,我的整个系统会冻结。这太疯狂了。我不想要它。我不需要