现象:XP环境下,在自己写的程序中,用::CreateFile()和::ReadFile()函数以二进制模式顺序读取一较大文件(约500M)左右,频繁顺序读取不超过1M的数据进入同一块内存,直至文件结束。奇怪现象:在读取过程中,通过任务管理器发现总的可用物理内存一直持续下降,系统缓存轻微持续上涨,但是任务列表中没有任何程序的内存持续上涨,包括我自己的进程(约占20M),都稳定在一个水平,当最终文件读取完毕时,可用物理内存已经降低至非常少了(只有约60-70M,总共512M,程序执行前约300M空闲),此时系统性能明显下降,关闭文件后,可用物理内存数量恢复,系统性能也恢复。问题:
::ReadFile()读取文件时,Windows会缓存所有已经读取的数据吗?如果不是,Windows会缓存多少数据?如何使Windows只缓存少量数据或者不缓存数据,从而达到操作大型文件时也能保持较多的物理内存和较好的系统性能?望高手不吝赐教和讨论,若觅得答案,分数一定及时奉上,谢谢!
::ReadFile()读取文件时,Windows会缓存所有已经读取的数据吗?如果不是,Windows会缓存多少数据?如何使Windows只缓存少量数据或者不缓存数据,从而达到操作大型文件时也能保持较多的物理内存和较好的系统性能?望高手不吝赐教和讨论,若觅得答案,分数一定及时奉上,谢谢!
联合使用FILE_FLAG_OVERLAPPED更好
1、跟踪直 CReadFile 内查看 MFC 代码,看其是怎样使用内存的
2、查看有无手工释放无用内存(缓存)的API
class CEosFontData
{
public:
public:
BYTE *m_pFileMap;
protected:
HANDLE m_FileHandle;
HANDLE m_MapHanle;
public:
BOOL OpenFile(CString strPathName);
void SetCharData();
BOOL CloseFile();
};
BOOL CEosFontData::OpenFile(CString strPathName)
{
m_FileHandle = CreateFile(strPathName,GENERIC_READ,FILE_SHARE_READ,
0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(m_FileHandle == INVALID_HANDLE_VALUE)
return FALSE;
m_MapHanle = CreateFileMapping(m_FileHandle,0,PAGE_READONLY,0,0,0);
if(!m_MapHanle)
return FALSE;
m_pFileMap = (BYTE*)MapViewOfFile(m_MapHanle,FILE_MAP_READ,0,0,0);
if(!m_pFileMap)
return FALSE;
return TRUE;
}
BOOL CEosFontData::CloseFile()
{
if(!UnmapViewOfFile(m_pFileMap))
return FALSE;
CloseHandle(m_FileHandle);
CloseHandle(m_MapHanle);
return TRUE;
}利用上面的打开/关闭文件,打开后用m_pFileMap一次访问文件内容就可以了,跳过内容直接用指针的移动。
用内存映射文件的方式的话,Windows就不会缓存了吗?这是为什么呢?to Snow_Ice11111(雪上加冰):
我只在开始分配了一小块内存,然后所有读取的数据都放到这块内存中,每次都覆盖,最后才释放。Windows自己缓存文件根VirtualAlloc()和VirtualFree()函数有什么关系呀?
CreateFile()函数使用时,系统不会立即把文件的所有内容读进内存中,不过当你读取其中的部分数据后,为了加快你再次访问这块数据的速度,它会把这块数据缓存在物理存储器中(这里没用内存这个词是因为系统可能把它放在磁盘的页文件中),这时程序所占用的内存和你存放数据所用的变量占用的内存无关,所以即使用VirtualAlloc()和VirtualFree()自己管理内存的使用和回收也不会有什么改善。回到你的问题中来,如果想避免程序占用资源过多,你试着用CloseHandle()关闭该文件,然后再次打开看效果如何。BTW: 我现在在用的visual-studio-booster就是你在CSDN发的散分贴时送的注册号,很好用!再次感谢一下!!