无法释放 C++ 中 CreateFileMapping 和 MapViewOfFile 创建的共享内存

Posted

技术标签:

【中文标题】无法释放 C++ 中 CreateFileMapping 和 MapViewOfFile 创建的共享内存【英文标题】:Cannot release shared memory created by CreateFileMapping and MapViewOfFile in C++ 【发布时间】:2014-02-05 21:32:42 【问题描述】:

我正在学习在 C++ 中使用共享内存。我发现在 Windows 下我需要使用 CreateFileMapping 和 MapViewOfFile 函数。我想分享 char 数组,所以我的部分代码是:

HANDLE hBuffer = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, bufferName);
char * buffer = (char *) MapViewOfFile(hBuffer, FILE_MAP_ALL_ACCESS, 0, 0, size);

(当然会检查 NULL)并且在使用共享内存结束时我调用:

UnmapViewOfFile(buffer); // returned true
CloseHandle(hBuffer); // returned true also

但是在资源监视器中我可以看到没有释放内存。多次调用时,应用程序分配的内存在增加,但没有释放。我究竟做错了什么?还是有其他释放共享内存的函数?

感谢您的回答。

【问题讨论】:

您在资源监视器中的读数是什么?你看的是提交大小还是工作集大小? 在所有访问它的应用程序释放它/关闭它们的句柄之前,不会释放内存。例如,两个应用程序映射共享一个内存映射。一个应用程序关闭它的句柄,内存映射仍然存在,直到第二个应用程序做同样的事情。 您的代码看起来找到了(嗯,...您拼错了 HANDLE),您可以使用 sysinternals 中的 procexp.exe 按名称查找您的 HANDLE(如果未找到则关闭),也在性能选项卡上观察你的应用程序的虚拟大小如何变化,还有句柄数应该相应地改变。 另外,观察在 MapViewOfFile 之后执行 memset(buffer,0,size); 之后会发生什么 - 这实际上是系统提交内存和工作集上升的时间。 我上面的评论是错误的,CreateFileMapping 默认应用 SEC_COMMIT 提交内存。但我想你的内存是分页的,直到调用 memset,之后调用分页页面被移动到物理内存,这会增加工作集....如果我没有错... 【参考方案1】:

感谢 marcin_j 解决了问题:

您的代码看起来找到了(嗯,...您拼错了 HANDLE),您可以使用 来自 sysinternals 的 procexp.exe 按名称查找您的 HANDLE(如果是 未找到然后它被关闭),还观察性能选项卡如何 您的应用程序的虚拟大小发生变化,还有句柄数 应该相应地改变。

另外,观察执行后会发生什么 memset(缓冲区,0,大小);在 MapViewOfFile 之后 - 这实际上是 系统将提交内存以及您的工作集何时上升。

我上面的评论是错误的,CreateFileMapping 默认适用 SEC_COMMIT 提交内存。但我想你的记忆是分页的 直到调用 memset,在调用之后分页页面被移动到 物理内存,增加工作集....如果我没记错的话...

【讨论】:

以上是关于无法释放 C++ 中 CreateFileMapping 和 MapViewOfFile 创建的共享内存的主要内容,如果未能解决你的问题,请参考以下文章

使用 C++ 的 DBus Glib:无法创建 DBusGProxy,释放它并再次创建它

Java中有类似C++ 的delete ,free语句来释放资源吗

c++单例模式为啥不在析构函数中释放静态的单例对象,而要加一个内嵌类

内存泄漏与内存溢出

C++之智能指针

是否可以从 C++ 释放分配的内存输出