VirtualMemorySize64 和 PrivateMemorySize64 有什么区别

What is the difference between VirtualMemorySize64 and PrivateMemorySize64

不明白Process.PrivateMemorySize64 and Process.VirtualMemorySize64

的区别

我创建了一个简单的控制台应用程序,它将 10 兆字节的 10 倍分配到一个字节数组中。

const int tenMegabyte = 1024*1024*10;
long allocatedMemory = 0;
List<byte[]> memory = new List<byte[]>();
for (int i = 0; i < 10; i++)
{
    allocatedMemory += tenMegabyte;
    Console.WriteLine("Allocated memory:    " + PrettifyByte(allocatedMemory));
    Console.WriteLine("VirtualMemorySize64: " + PrettifyByte(Process.GetCurrentProcess().VirtualMemorySize64));
    Console.WriteLine("PrivateMemorySize64: " + PrettifyByte(Process.GetCurrentProcess().PrivateMemorySize64));
    Console.WriteLine();
    memory.Add(new byte[tenMegabyte]);
}

PrivateMemorySize64 的工作方式与我预期的一样:它以一定大小开始,并随着分配的内存而增长。

但 VirtualMemorySize64 似乎在一开始就为控制台应用程序分配了大量内存(32 位 180mb,64 位 560mb)

问题:

VirtualMemorySize 测量进程使用的 all 虚拟内存。其中包括您计算机上所有其他进程共享的页面。在 .NET 程序中包括操作系统、CLR、抖动和 ngen-ed Framework 程序集。

PrivateMemorySize 测量专用于您的进程且不能被其他进程共享的虚拟内存。在 .NET 程序中,它包括所有数据和任何非 ngen-ed 的 jitted 代码。

两者都是虚拟内存测量值,在内部仅表示为处理器的数字。每 4096 字节内存各一个。实际 RAM 使用量是一个非常不同的数字,由 Process.WorkingSet 表示。通常不是很有用,当其他进程需要 RAM 并且您使用的某些内容需要映射时,它可以非常迅速地改变。您的操作系统和 .NET 都经过优化以使用大量 VM,现代机器上有很多 VM 可用,它胜过替代品,即磁盘。

Is the PrivateMemorySize part of the VirtualMemorySize? If this is true, what is the rest of the VirtualMemorySize? Is it just reserved memory, or is this actually in ram/page file?

是的。其余部分是第一段所述的共享内存

Why does even a simple console application allocate more than 500mb VirtualMemory?

无论是操作系统还是 .NET 运行时,您的控制台应用程序都不是小的部分,执行它仍然需要两者。由于它们由所有进程共享,因此您不必太在意它。你也无能为力。 "big" 控制台应用程序通常不会添加那么多 VM,除非它分配大量内存。

If my application use 1GB of PrivateMemorySize and 20GB of VirtualMemorySize, should i care or can this be ignored?

1GB 的私有内存没什么好担心的。 20GB 的 VM 越来越多了。 GC 堆的大小值得关注,当它必须遍历数 GB 的堆时,收集可能会变慢。

Why does the 64bit version of the program allocate so much more VirtualMemory?

好吧,64 是 2 * 32。这并不能像那样扩展,64 位进程仍然倾向于使用大量 int。编写现代 64 位 OS 是为了假设有大量可用的硬件资源,Win8 确实需要 8 GB 的 RAM 才能顺利运行。

您提供的链接说明了问题:

私有内存大小:

The value returned by this property represents the current size of memory used by the process that cannot be shared with other processes.

虚拟内存大小:

The value returned by this property represents the current size of virtual memory used by the process. The operating system maps the virtual address space for each process either to pages loaded in physical memory, or to pages stored in the virtual memory paging file on disk.

所以第一个告诉你的应用程序通过它自己的内存分配消耗了多少内存,后者告诉它映射了多少内存(意味着使用的整个内存 space,包括 PrivateMemorySize),包括操作系统和 .NET 框架库。

Is the PrivateMemorySize part of the VirtualMemorySize?

是的。一切都是 VirtualMemorySize 的一部分,除非您编写内核驱动程序,在这种情况下您可能会谈论物理 RAM。

If this is true, what is the rest of the VirtualMemorySize?

  • 加载到进程中的 DLL
  • 映射文件
  • .NET 编译的 IL 代码
  • 默认进程堆
  • 堆栈
  • TEB(线程环境块)和PEB(进程环境块)
  • C++ 堆如果你做 P/Invoke 或类似的东西
  • 直接调用 VirtualAlloc()

Is it just reserved memory, or is this actually in ram/page file?

虚拟内存可以保留(不可用)或提交(准备好使用)。保留部分既不在RAM中也不在页面文件中。

Why does even a simple console application allocate more than 500mb VirtualMemory?

您可以使用调试器查找它,例如WinDbg。 这是我在 64 位 OS.

上的 .NET 4.5 32 位程序(您的代码)
0:005> .loadby sos clr
0:005> !address -summary
--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free                                     59          edb72000 (   3.714 GB)           92.86%
<unknown>                               119           ceca000 ( 206.789 MB)  70.70%    5.05%
Image                                   222           3220000 (  50.125 MB)  17.14%    1.22%
MappedFile                               15           1b7c000 (  27.484 MB)   9.40%    0.67%
Stack                                    18            600000 (   6.000 MB)   2.05%    0.15%
Heap                                     12            1e0000 (   1.875 MB)   0.64%    0.05%
Other                                     8             31000 ( 196.000 kB)   0.07%    0.00%
TEB                                       6              6000 (  24.000 kB)   0.01%    0.00%
PEB                                       1              1000 (   4.000 kB)   0.00%    0.00%

<unknown> 部分包括 .NET 内存。在这种情况下,它可能 .NET,因为我没有 C++ 或 VirtualAlloc() 调用。

还可以看到 .NET 当前仅使用了 206 MB 中的 105 MB:

0:005> !eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x02741018
generation 1 starts at 0x0274100c
generation 2 starts at 0x02741000
ephemeral segment allocation context: none
 segment     begin  allocated      size
02740000  02741000  027afff4  0x6eff4(454644)
Large object heap starts at 0x03741000
 segment     begin  allocated      size
03740000  03741000  04193fe8  0xa52fe8(10825704)
04860000  04861000  05261020  0xa00020(10485792)
05990000  05991000  06391020  0xa00020(10485792)
06be0000  06be1000  075e1020  0xa00020(10485792)
07be0000  07be1000  085e1020  0xa00020(10485792)
08be0000  08be1000  095e1020  0xa00020(10485792)
09be0000  09be1000  0a5e1020  0xa00020(10485792)
0b070000  0b071000  0ba71020  0xa00020(10485792)
0c070000  0c071000  0ca71020  0xa00020(10485792)
0d070000  0d071000  0da71020  0xa00020(10485792)
Total Size:              Size: 0x64c20fc (105652476) bytes.
------------------------------
GC Heap Size:    Size: 0x64c20fc (105652476) bytes.

我们可以看到总共保留了 131 MB:

0:005> !address -summary
--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE                                 59          edb72000 (   3.714 GB)           92.86%
MEM_COMMIT                              302           a114000 ( 161.078 MB)  55.07%    3.93%
MEM_RESERVE                              99           836a000 ( 131.414 MB)  44.93%    3.21%

If my application use 1GB of PrivateMemorySize and 20GB of VirtualMemorySize, should i care or can this be ignored?

如果不知道您的流程预期做什么,您就无法判断。您可能使用了过度使用内存的第三部分 DLL,例如用于数据分析。那就好了。

一般来说,您的产品应该得到一种"feeling"。如果行为发生巨大变化,那么我会开始调查。

Why does the 64bit version of the program allocate so much more VirtualMemory?

可能是因为 .NET 不必担心其他事情。

在32位上,只有4GB内存,.NET需要确保可以加载其他DLL,可以创建线程等。在64位上,8TB内存,总会有1MB离开以创建新线程。