Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 什么是;“私人数据”;在VMMAP中定义?_C#_C++_Winapi_Memory_Vmmap - Fatal编程技术网

C# 什么是;“私人数据”;在VMMAP中定义?

C# 什么是;“私人数据”;在VMMAP中定义?,c#,c++,winapi,memory,vmmap,C#,C++,Winapi,Memory,Vmmap,我正在使用VMMap分析混合模式(托管和非托管)应用程序中的虚拟/进程地址空间利用率。我了解Windows VMM和虚拟内存API的工作原理,我也了解堆内存API的工作原理。我已经看过了我正在使用的CRT实现(不是很详细),并且(我想这可能是我的失败)理解了它是如何使用前面提到的Win32 API的 我希望了解这个“私人数据”统计数据向我展示了什么。我的应用程序不直接调用任何Win32内存API函数,它只在“C++”中使用“MalC/Cn新建”和“C”中的“新”(下面是使用Win32内存管理AP

我正在使用VMMap分析混合模式(托管和非托管)应用程序中的虚拟/进程地址空间利用率。我了解Windows VMM和虚拟内存API的工作原理,我也了解堆内存API的工作原理。我已经看过了我正在使用的CRT实现(不是很详细),并且(我想这可能是我的失败)理解了它是如何使用前面提到的Win32 API的

我希望了解这个“私人数据”统计数据向我展示了什么。我的应用程序不直接调用任何Win32内存API函数,它只在“C++”中使用“MalC/Cn新建”和“C”中的“新”(下面是使用Win32内存管理API)。 VMMap给出的“私有数据”定义为:

私有内存是由VirtualAlloc分配的内存,而不是 由堆管理器或.NET运行时进行子分配。信息技术 无法与其他进程共享,由系统收费 提交限制,通常包含应用程序数据

所以我猜这个定义让我问,好吧,那么谁在给VirtualAlloc打电话呢?是堆管理器还是.Net运行时

我可以获得一些已提交的私人数据的地址,并使用WinDbg查找。。。。好。。。事实证明,微软在他们的智慧中屏蔽了ntdll公共符号,所以WinDbg的工作并不是很好——如果有要求,我可以提供更多的细节,但基本上像这样的命令!地址-由于缺少符号,摘要不再工作

另一种方法来解释这个问题:C++写的代码或C代码可以导致这个私有数据统计增加或减少?或者,这一切都是由OS、C++运行时还是.NET运行时管理的,因此,任凭其一时兴起?< /P> 我可以从VMMap的性质(其他内存类型相互排斥)推断,此“私有数据”因此不能是以下任何类型的地址空间:

  • 堆(注意,这包括提交和保留的堆空间-保留 通过调用VirtualAlloc,如 私人数据(见上文)
  • 托管堆
  • 堆叠
  • 可分享
  • 映射文件
  • 形象
  • 页表
  • 无用的
  • 免费的
(我找不到一个在线帮助文件,该文件定义了VMMap认为上述所有类型是什么,但这里有一个下载帮助文件的链接:)

我注意到,在我的应用程序中,私有数据的总大小(保留的和提交的)在我的应用程序生命周期中保持相当恒定,尽管堆/托管堆/堆栈大小按预期变化。我还注意到,在私有数据使用的~250Mb总容量中,只有~33Mb是实际提交的。请注意,我的测量方法相当简单,因此值可能在每次测量之间发生变化,而我只是看不到(如果我知道这是测量什么,我可以使用DebugDiag在相关计数器达到某个阈值(鸡和蛋)时获取进程转储)

我目前的推测理论是,这是一个被保留的空间,当本地人(或者我想是被管理的?)达到他们的能力时,他们会堆积到其中,但我没有得到任何证据来证明这一点。因此,它仍牢牢地留在投机性资产堆中

在互联网上搜索有关这方面的详细信息可能会很痛苦,有许多帖子/文章/博客混淆了事情,使用了自引用定义(Performance Monitor的工作集定义的第一句就是一个很好的例子),不完整或完全错误。许多地方模糊了定义或使用了不一致的术语(请注意,VMMaps定义了字段私有数据,并将其称为私有内存,可能有点像肛门的抱怨,但含糊不清)

现在,我已经批评了互联网上的其他人把事情搞得一团糟和不正确。。。如果上述内容有任何不合理之处,或者您可以向我展示相反的文档,或者您需要更明确的定义,请告诉我,我也会将自己列入违规者名单!我想在网上向某人解释记忆问题的前半部分是确保我们都在谈论同一件事

最后这个问题:暗示我可能永远也找不到答案:/


更新/编辑:我发现,通过启用gflags用户堆栈跟踪(gflags-I myapp.exe+ust),可以增加私有数据的大小,我假设这是回溯数据库,但即使没有gflags,仍然有私有数据,我很难解释。

我知道这是一个非常老的问题。但由于某种原因,它仍然没有得到回答。萨沙·戈尔茨坦(Sasha Goldstein)在DotNext会议上谈到WinDbg时提到了这个问题。 关键是,在WinDbg的帮助下,可以很容易地回答这个问题

为了回答CLR是否将VirtualAlloc用于其堆,我们将使用打印当前堆栈(本机和托管)的脚本在此函数处设置一个断点

此处:
k5
打印本机调用堆栈的最后5帧并
!clrstack
(来自SOS)打印托管堆栈<代码>gc继续执行

请注意,此脚本仅适用于x86进程。对于x64,您需要一些其他的(注册表和调用约定不同)

然后我创建了一个简单的程序,分配一个对象并将其添加到列表中

    static void Main(string[] args)
    {
        var list = new List<string[]>();
        while (true) {
            var a = Console.ReadLine();
            if (a == "q" || a == "Q") break;
            var arr = new string[100];
            list.Add(arr);
        }
    }
static void Main(字符串[]args)
{
var list=新列表();
while(true){
var a=Console.ReadLine();
如果(a==“q”| a==“q”)中断;
var arr=新字符串[100];
列表。添加(arr);
}
}
在WinDbg下运行它并开始按Enter键。在某个时刻,断点命中列表将在堆中扩展并分配额外内存:

所以很明显CLR使用了VirtualAlloc fo
    static void Main(string[] args)
    {
        var list = new List<string[]>();
        while (true) {
            var a = Console.ReadLine();
            if (a == "q" || a == "Q") break;
            var arr = new string[100];
            list.Add(arr);
        }
    }
lkd> !process 0n12876
PROCESS fffffa802e058600
    SessionId: 1  Cid: 324c    Peb: 7fffffdf000  ParentCid: 0bec
    DirBase: 22211000  ObjectTable: fffff8a00e9b1310  HandleCount:  85.
    Image: calc.exe
    VadRoot fffffa8039b76500 Vads 176 Clone 0 Private 1852. Modified 1. Locked 0.
.
.

lkd> !vad fffffa8039b76500
VAD             level      start      end    commit
.
.
fffffa803c9da680 ( 6)      ff7b0    ff892         6 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\calc.exe
.
.