用于确定VM碎片的.NET API

时间:2010-01-22 17:24:44

标签: .net virtual-memory

是否有用于获取有关VM使用的详细信息的.NET API?我特别感兴趣的是确定我的地址空间是多么碎片化。

谢谢!

5 个答案:

答案 0 :(得分:1)

简答:不。您需要使用Win32 API。我真的不知道你会使用什么API调用...

快速搜索http://www.pinvoke.net让我想到了这个:

[DllImport("coredll.dll", SetLastError=true)]
static extern void GlobalMemoryStatus(ref MEMORYSTATUS lpBuffer);

但是MEMORYSTATUS结构似乎没有你需要的所有信息(只是物理和虚拟内存使用和其他信息)。

你应该挖掘MSDN以找到必要的方法。

答案 1 :(得分:1)

可以让您对此有所了解的Windows API函数类型是VirtualQueryEx()枚举虚拟内存部分并发现未使用的空间,GetProcessHeaps()用于查找在进程内创建的堆和HeapWalk()以发现如何使用每个堆中的块。

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

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

答案 2 :(得分:0)

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

然而,这让我想到了下一点,您应该能够通过自己托管CLR来获取此信息。您可能需要查看this blog post about this topic

答案 3 :(得分:0)

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

但是,您可以使用Virtual Memory Validator(商业但免费)来可视化虚拟内存空间,还可以逐页和逐段检查内存空间。首先查看视觉效果,因为这样可以轻松查看一般问题和趋势。当您确定哪些内存区域存在问题时,请查看页面和段落的详细信息。

这是一篇描述pages and paragraphs是什么的博客文章。

答案 4 :(得分:0)

在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(),在这种情况下,您需要第二个循环来遍历所有堆。我不知道为什么他们不止一个。

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