C++ 什么Alloc API可以在内部调用VirtualAlloc/保留内存?
我正在调试调试DLL中潜在的内存泄漏问题 在这种情况下,进程运行一个子测试,动态加载/卸载DLL,在测试过程中保留并提交了大量内存(1.3GB)。测试完成并卸载DLL后,仍保留大量内存(1.2GB) 我之所以说这个保留内存是由DLL分配的,是因为如果我使用一个发布DLL(没有其他更改,相同的测试),保留内存是~300MB,所以所有额外的保留内存都必须在调试DLL中分配 看起来在测试期间提交了大量内存,但在测试之后取消了提交(而不是释放到可用状态)。所以我想追踪谁保留/取消了这么大的内存。但在源代码中,没有调用VirtualAlloc,所以问题是:C++ 什么Alloc API可以在内部调用VirtualAlloc/保留内存?,c++,windows,winapi,dll,virtual-memory,C++,Windows,Winapi,Dll,Virtual Memory,我正在调试调试DLL中潜在的内存泄漏问题 在这种情况下,进程运行一个子测试,动态加载/卸载DLL,在测试过程中保留并提交了大量内存(1.3GB)。测试完成并卸载DLL后,仍保留大量内存(1.2GB) 我之所以说这个保留内存是由DLL分配的,是因为如果我使用一个发布DLL(没有其他更改,相同的测试),保留内存是~300MB,所以所有额外的保留内存都必须在调试DLL中分配 看起来在测试期间提交了大量内存,但在测试之后取消了提交(而不是释放到可用状态)。所以我想追踪谁保留/取消了这么大的内存。但在源代
system\u INFO.dwAllocationGranularity
的值来检索)。HeapAlloc()允许您以所需的任何粒度分配较小的内存块,这更适合于典型的应用程序编程。在内部,HeapAlloc()处理调用VirtualAlloc()以获取一个大的块,然后根据需要对其进行分割。这不仅提供了一个更简单的API,而且效率更高
请注意,C运行时库(CRT)提供的内存分配函数——即C的malloc()和C++的新操作符——是一个更高的级别。它们构建在HeapAlloc()之上(至少在Microsoft的CRT实现中)。在内部,它们分配相当大的内存块,基本上用作应用程序的“主”内存块,然后根据请求将其划分为更小的块。释放/删除这些块时,它们将返回到池中。再一次,这个额外的层提供了一个简化的接口(特别是编写独立于平台的代码的能力),并且在一般情况下提高了效率
各种OS API提供的内存映射文件和其他功能也构建在虚拟内存子系统上,因此在内部调用VirtualAlloc()(或更低级别的等效程序)
因此,基本上,正常Windows应用程序的最低级别内存分配例程是VirtualAlloc()。但这并不意味着它是通常用于内存分配的主要功能。只有在实际需要其附加功能时才调用VirtualAlloc()。否则,请使用标准库的内存分配例程,或者如果您有一些令人信服的理由避免使用这些例程(如不链接到CRT或创建自己的自定义内存池),请调用HeapAlloc()
还要注意,您必须始终使用与分配内存所用的机制相对应的机制来释放内存。仅仅因为所有内存分配函数最终都调用VirtualAlloc(),并不意味着您可以通过调用VirtualFree()释放内存。如上所述,这些其他函数在VirtualAlloc()之上实现额外的逻辑,因此需要调用它们自己的例程来释放内存。仅当通过调用VirtualAlloc()自行分配内存时,才调用VirtualFree()。如果内存是用HeapAlloc()分配的,则调用HeapFree()。对于malloc(),调用free();要获取新信息,请调用delete
至于你问题中描述的具体情况,我不清楚你为什么担心这一点。记住保留内存和提交内存之间的区别是很重要的。Reserved仅仅意味着地址空间中的这个特定块已被保留供进程使用。无法使用保留块。为了使用内存块,必须提交它,这是指在页文件或物理内存中为内存分配备份存储的过程。这有时也称为映射。保留和提交可以作为两个单独的步骤进行,也可以同时进行。例如,您可能想保留一个连续的地址空间供将来使用,但实际上您还不需要它,所以您不提交它。已保留但未提交的内存实际上未分配 事实上,所有这些保留内存可能根本不是泄漏。调试中使用的一种相当常见的策略是保留特定范围的me