简体   繁体   English

VirtualMemorySize64和PrivateMemorySize64之间的区别是什么

[英]What is the difference between VirtualMemorySize64 and PrivateMemorySize64

I do not understand the difference between Process.PrivateMemorySize64 and Process.VirtualMemorySize64 我不明白Process.PrivateMemorySize64Process.VirtualMemorySize64之间的区别

I have created a simple console application which allocates 10 times 10 megabyte into an byte array. 我创建了一个简单的控制台应用程序,它将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]);
}

The PrivateMemorySize64 works as i did expect: It starts with a certain size, and grows with the allocated memory. PrivateMemorySize64按照我的预期工作:它以一定的大小开始,并随着分配的内存而增长。

But the VirtualMemorySize64 seems to allocate a lot of memory at the very start even for a console application (180mb for 32bit and 560mb for 64bit) 但VirtualMemorySize64似乎在一开始就分配了大量内存,即使对于一个控制台应用程序(180位为32位,560位为64位)

32位内存分配样本32位内存分配样本

Questions: 问题:

  • Is the PrivateMemorySize part of the VirtualMemorySize? VirtualMemorySize的PrivateMemorySize是一部分吗? If this is true, what is the rest of the VirtualMemorySize? 如果是这样,那么VirtualMemorySize的其余部分是什么? Is it just reserved memory, or is this actually in ram/page file? 它只是保留内存,还是实际上是ram / page文件?
  • Why does even a simple console application allocate more than 500mb VirtualMemory? 为什么即使是一个简单的控制台应用程序也会分配超过500mb的VirtualMemory?
  • If my application use 1GB of PrivateMemorySize and 20GB of VirtualMemorySize, should i care or can this be ignored? 如果我的应用程序使用1GB的PrivateMemorySize和20GB的VirtualMemorySize,我应该关心还是可以忽略它?
  • Why does the 64bit version of the program allocate so much more VirtualMemory? 为什么64位版本的程序分配了更多的VirtualMemory?

VirtualMemorySize measures all of the virtual memory that your process uses. VirtualMemorySize测量进程使用的所有虚拟内存。 Which includes the pages shared by all other processes on your machine. 其中包括计算机上所有其他进程共享的页面。 Which in a .NET program includes the operating system, CLR, jitter and the ngen-ed Framework assemblies. 在.NET程序中包含操作系统,CLR,抖动和ngen-ed框架程序集。

PrivateMemorySize measures the virtual memory that's dedicated to your process and cannot be shared by other processes. PrivateMemorySize测量专用于您的进程的虚拟内存,并且不能由其他进程共享。 Which in a .NET program includes all the data and any jitted code that isn't ngen-ed. 在.NET程序中包含所有数据和任何非编译的jitted代码。

Both are virtual memory measurements, internally represented as just numbers to the processor. 两者都是虚拟内存测量,内部表示为处理器的数字。 One each for every 4096 bytes of memory. 每4096字节的内存一个。 Actual RAM usage is a very different number, represented by Process.WorkingSet. 实际的RAM使用量是一个非常不同的数字,由Process.WorkingSet表示。 Not generally useful, it can change very rapidly when other processes require RAM and some of what you use needs to be mapped out. 通常不太有用,当其他进程需要RAM时,它可以非常快速地改变,并且您需要将一些使用的内容映射出来。 Both your operating system and .NET were optimized to use lots of VM, there is a lot of it available on modern machines and it beats the alternative, the disk. 你的操作系统和.NET都经过优化,可以使用大量的虚拟机,在现代机器上可以使用很多虚拟机,它可以替代磁盘。

Is the PrivateMemorySize part of the VirtualMemorySize? VirtualMemorySize的PrivateMemorySize是一部分吗? If this is true, what is the rest of the VirtualMemorySize? 如果是这样,那么VirtualMemorySize的其余部分是什么? Is it just reserved memory, or is this actually in ram/page file? 它只是保留内存,还是实际上是ram / page文件?

Yes. 是。 The rest is shared memory as noted in the first paragraph 其余的是共享内存,如第一段所述

Why does even a simple console application allocate more than 500mb VirtualMemory? 为什么即使是一个简单的控制台应用程序也会分配超过500mb的VirtualMemory?

Neither the operating system nor the .NET runtime is partial to your console app being small, both are still needed to execute it. 操作系统和.NET运行时都不会偏向于您的控制台应用程序很小,仍然需要它们来执行它。 Since they are shared by all processes, you don't care that much about it. 由于它们由所有进程共享,因此您并不关心它。 Nor is there anything you can do about it. 你也没有什么可以做的。 A "big" console app doesn't usually add that much more VM unless it allocates a lot of memory. “大”控制台应用程序通常不会添加更多VM,除非它分配了大量内存。

If my application use 1GB of PrivateMemorySize and 20GB of VirtualMemorySize, should i care or can this be ignored? 如果我的应用程序使用1GB的PrivateMemorySize和20GB的VirtualMemorySize,我应该关心还是可以忽略它?

1GB of private memory isn't much to worry about. 1GB的私人内存不用担心。 20GB of VM is getting excessive. 20GB的VM过多。 The size of the GC heap is the one to watch, collections can get slow when it has to plow through multiple gigabytes of heap. GC堆的大小是值得关注的,当必须通过数千兆字节的堆时,集合可能会变慢。

Why does the 64bit version of the program allocate so much more VirtualMemory? 为什么64位版本的程序分配了更多的VirtualMemory?

Well, 64 is 2 * 32. That doesn't quite scale like that, a 64-bit process still tends to use plenty of ints . 好吧,64是2 * 32.这并不像那样,64位进程仍然倾向于使用大量的整数 A modern 64-bit OS was written to assume plenty of hardware resources to be available, Win8 does require 8 GB of RAM to work smoothly. 编写一个现代的64位操作系统来假设有大量的硬件资源可供使用,Win8需要8 GB的RAM才能顺利运行。

Is the PrivateMemorySize part of the VirtualMemorySize? VirtualMemorySize的PrivateMemorySize是一部分吗?

Yes. 是。 Everything is part of VirtualMemorySize, unless you write kernel drivers in which case you might talk about physical RAM. 一切都是VirtualMemorySize的一部分,除非您编写内核驱动程序,在这种情况下您可能会谈论物理RAM。

If this is true, what is the rest of the VirtualMemorySize? 如果是这样,那么VirtualMemorySize的其余部分是什么?

  • DLLs loaded into the process DLL加载到进程中
  • mapped files 映射文件
  • .NET IL code that gets compiled .NET IL代码被编译
  • the default process heap 默认进程堆
  • stack
  • TEB (thread environment block) and PEB (process environment block) TEB(线程环境块)和PEB(进程环境块)
  • C++ heaps if you do P/Invoke or similar stuff 如果你做P / Invoke或类似的东西,C ++会堆积
  • direct calls to VirtualAlloc() 直接调用VirtualAlloc()

Is it just reserved memory, or is this actually in ram/page file? 它只是保留内存,还是实际上是ram / page文件?

Virtual memory can be reserved (unusable) or committed (ready for use). 虚拟内存可以保留(不可用)或已提交(可供使用)。 The reserved parts are neither in RAM nor in page file. 保留的部分既不在RAM中也不在页面文件中。

Why does even a simple console application allocate more than 500mb VirtualMemory? 为什么即使是一个简单的控制台应用程序也会分配超过500mb的VirtualMemory?

You can look it up with a debugger, eg WinDbg. 您可以使用调试器查找它,例如WinDbg。 Here's my .NET 4.5 32 bit program (your code) on a 64 bit OS. 这是64位操作系统上的.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%

The <unknown> part includes .NET memory. <unknown>部分包括.NET内存。 In this case it's likely only .NET, since I have no C++ or VirtualAlloc() calls. 在这种情况下,它可能只有 .NET,因为我没有C ++或VirtualAlloc()调用。

It's also possible to see that .NET currently uses only 105 MB of those 206: 也可以看到.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.

And we can see that in total, 131 MB are reserved: 我们可以看到总共保留了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? 如果我的应用程序使用1GB的PrivateMemorySize和20GB的VirtualMemorySize,我应该关心还是可以忽略它?

You can't tell that without knowing what your process is expected to do. 如果不知道您的流程预期会做什么,您无法分辨。 It's possible that you use a 3rd part DLL that makes excessive use of memory, eg for data analytics. 您可能使用过度使用内存的第三方DLL,例如用于数据分析。 Then it's ok. 那没关系。

In general, you should get a kind of "feeling" for your product. 一般来说,你应该对你的产品有一种“感觉”。 If the behavior changes massively, then I would start investigation. 如果行为大规模改变,那么我会开始调查。

Why does the 64bit version of the program allocate so much more VirtualMemory? 为什么64位版本的程序分配了更多的VirtualMemory?

Likely because .NET does not have to worry about other things. 可能因为.NET不必担心其他事情。

On 32 bit, with only 4 GB of memory, .NET needs to ensure that other DLLs can be loaded, threads can be created etc. On 64 bit, with 8 TB of memory, there will always be 1 MB left to create a new thread. 在32位,只有4 GB的内存,.NET需要确保可以加载其他DLL,可以创建线程等。在64位,8 TB的内存,将始终有1 MB来创建一个新的线。

The links you provided explain the matter: 您提供的链接解释了这个问题:

PrivateMemorySize: PrivateMemorySize:

The value returned by this property represents the current size of memory used by the process that cannot be shared with other processes. 此属性返回的值表示进程使用的当前内存大小,该内存无法与其他进程共享。

VirtualMemorySize: VirtualMemorySize:

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. 操作系统将每个进程的虚拟地址空间映射到物理内存中加载的页面,或映射到磁盘上虚拟内存页面文件中存储的页面。

So the first one tells how much memory your application is consuming by its own memory allocations, the latter tells how much memory is mapped to it (meaning the whole memory space used, including the PrivateMemorySize), including operating system and .NET framework libraries. 因此,第一个通过自己的内存分配来说明应用程序消耗了多少内存,后者告诉它有多少内存映射到它(意味着使用的整个内存空间,包括PrivateMemorySize),包括操作系统和.NET框架库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么.net程序在计算机有更多内存时会使用更多的VirtualMemorySize64 - Why does a .net program use more VirtualMemorySize64 when the computer has more ram 为什么 Process.PrivateMemorySize64 /1024 与 Windows Task Manager Memory (Private Working Set) 不匹配? - Why does Process.PrivateMemorySize64 /1024 not match what Windows Task Manager Memory (Private Working Set)? Process.PrivateMemorySize64在多次迭代中返回相同的值 - Process.PrivateMemorySize64 Returns The Same Value Over Multiple Iterations Process.PrivateMemorySize64返回已提交的内存,而不是私有的 - Process.PrivateMemorySize64 returning committed memory instead of private 确定Int64变量和Int64.MaxValue之间的差异的最佳方法是什么? - What's the best method of determining the difference between an Int64 variable and Int64.MaxValue? Process.WorkingSet64和Process.PeakWorkingSet64之间的区别 - Difference between Process.WorkingSet64 and Process.PeakWorkingSet64 Point vs MCvPoint2D64f,它们有什么区别? - Point vs MCvPoint2D64f, What is the difference between them? Convert.ToBase64String(byte [])和HttpServerUtility.UrlTokenEncode(byte [])有什么区别? - What is the difference between Convert.ToBase64String(byte[]) and HttpServerUtility.UrlTokenEncode(byte[])? UTF8/UTF16 和 Base64 在编码方面有什么区别 - What's the difference between UTF8/UTF16 and Base64 in terms of encoding int、Int16、Int32 和 Int64 之间有什么区别? - What is the difference between int, Int16, Int32 and Int64?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM