用于确定VM碎片的.NET API

用于确定VM碎片的.NET API,.net,virtual-memory,.net,Virtual Memory,是否有一个.NETAPI用于获取有关VM使用的详细信息?我特别感兴趣的是确定我的地址空间有多分散 谢谢 简短回答:不。你需要打开Win32 API才能做到这一点。我真的不知道你会用什么API调用 快速搜索后,我发现: [DllImport("coredll.dll", SetLastError=true)] static extern void GlobalMemoryStatus(ref MEMORYSTATUS lpBuffer); 但是MEMORYSTATUS结构似乎没有您需要的所有信息

是否有一个.NETAPI用于获取有关VM使用的详细信息?我特别感兴趣的是确定我的地址空间有多分散


谢谢

简短回答:不。你需要打开Win32 API才能做到这一点。我真的不知道你会用什么API调用

快速搜索后,我发现:

[DllImport("coredll.dll", SetLastError=true)]
static extern void GlobalMemoryStatus(ref MEMORYSTATUS lpBuffer);
但是MEMORYSTATUS结构似乎没有您需要的所有信息(只有物理和虚拟内存使用情况以及其他信息)


您应该深入研究MSDN以找到必要的方法。

这样的调用在托管世界中没有意义,因为不同的CLR主机可能处理不同的事情(如普通的应用程序主机或SQL Server)。别忘了GC可以移动东西,所以碎片不是真正的问题,因为GC会压缩堆


然而,这就引出了下一点,您应该能够通过自己托管CLR来获得这些信息。您可能想了解一下。

在这方面可以让您有所了解的Windows API函数有:VirtualQueryEx()用于枚举虚拟内存部分并查找未使用的空间;GetProcessHeaps()用于查找进程内部创建的堆;HeapWalk()用于查找每个堆中的块是如何使用的

这并不容易,尤其是HeapWalk()在正在运行的程序中是一个麻烦的函数。您应该看看SysInternals,它提供了出色的虚拟内存诊断


这样做的缺点是它不能真正帮助您解决内存碎片问题。您无法影响Windows内存管理器分配虚拟内存空间的方式。没有分配内存。如果你现在与OOM斗争,你真的应该考虑重新架构你的应用程序。或者切换到64位操作系统,两百美元的解决方案。

您确实需要深入到Win32/Win64 API中才能在页面级别获取此信息。任何更详细的信息,您都需要了解正在查看的堆的内部工作,无论是C堆、Win32堆、CLR小对象堆还是CLR大对象堆

但是,您可以使用(这是商业的,但是免费的)可视化虚拟内存空间,还可以逐页逐段地检查内存空间。首先看一下视觉效果,因为这样可以很容易地看到一般问题和趋势。当你决定哪些记忆区域有问题时,再看看页面和段落上的详细信息


下面是一篇博客文章,描述的是什么。

在C语言中,您可以编写类似的内容来了解分配了多少内存:

HANDLE heap = GetProcessHeap();
PROCESS_HEAP_ENTRY entry;
memset(&entry, 0, sizeof(entry));
unsigned long size = 0;
while(HeapWalk(heap, &entry)) {
    if(entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) {
        size += entry.cbData;
    }
}
如果使用其他堆,则可能需要GetProcessHeaps(),在这种情况下,您需要第二个循环来遍历所有堆。我不知道为什么他们会不止一个


在您的情况下,您可能应该计算块的数量及其大小。如果您想将其保存到磁盘,我建议您首先计算块的数量,分配一个缓冲区来保存所有信息,然后将缓冲区保存到一个文件中供以后查看。

VMMap应用程序非常棒。谢谢