![](/img/trans.png)
[英]Why does a .net program use more VirtualMemorySize64 when the computer has more ram
[英]What is the difference between VirtualMemorySize64 and PrivateMemorySize64
我不明白Process.PrivateMemorySize64和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似乎在一開始就分配了大量內存,即使對於一個控制台應用程序(180位為32位,560位為64位)
問題:
VirtualMemorySize測量進程使用的所有虛擬內存。 其中包括計算機上所有其他進程共享的頁面。 在.NET程序中包含操作系統,CLR,抖動和ngen-ed框架程序集。
PrivateMemorySize測量專用於您的進程的虛擬內存,並且不能由其他進程共享。 在.NET程序中包含所有數據和任何非編譯的jitted代碼。
兩者都是虛擬內存測量,內部表示為處理器的數字。 每4096字節的內存一個。 實際的RAM使用量是一個非常不同的數字,由Process.WorkingSet表示。 通常不太有用,當其他進程需要RAM時,它可以非常快速地改變,並且您需要將一些使用的內容映射出來。 你的操作系統和.NET都經過優化,可以使用大量的虛擬機,在現代機器上可以使用很多虛擬機,它可以替代磁盤。
VirtualMemorySize的PrivateMemorySize是一部分嗎? 如果是這樣,那么VirtualMemorySize的其余部分是什么? 它只是保留內存,還是實際上是ram / page文件?
是。 其余的是共享內存,如第一段所述
為什么即使是一個簡單的控制台應用程序也會分配超過500mb的VirtualMemory?
操作系統和.NET運行時都不會偏向於您的控制台應用程序很小,仍然需要它們來執行它。 由於它們由所有進程共享,因此您並不關心它。 你也沒有什么可以做的。 “大”控制台應用程序通常不會添加更多VM,除非它分配了大量內存。
如果我的應用程序使用1GB的PrivateMemorySize和20GB的VirtualMemorySize,我應該關心還是可以忽略它?
1GB的私人內存不用擔心。 20GB的VM過多。 GC堆的大小是值得關注的,當必須通過數千兆字節的堆時,集合可能會變慢。
為什么64位版本的程序分配了更多的VirtualMemory?
好吧,64是2 * 32.這並不像那樣,64位進程仍然傾向於使用大量的整數 。 編寫一個現代的64位操作系統來假設有大量的硬件資源可供使用,Win8需要8 GB的RAM才能順利運行。
VirtualMemorySize的PrivateMemorySize是一部分嗎?
是。 一切都是VirtualMemorySize的一部分,除非您編寫內核驅動程序,在這種情況下您可能會談論物理RAM。
如果是這樣,那么VirtualMemorySize的其余部分是什么?
它只是保留內存,還是實際上是ram / page文件?
虛擬內存可以保留(不可用)或已提交(可供使用)。 保留的部分既不在RAM中也不在頁面文件中。
為什么即使是一個簡單的控制台應用程序也會分配超過500mb的VirtualMemory?
您可以使用調試器查找它,例如WinDbg。 這是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%
<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%
如果我的應用程序使用1GB的PrivateMemorySize和20GB的VirtualMemorySize,我應該關心還是可以忽略它?
如果不知道您的流程預期會做什么,您無法分辨。 您可能使用過度使用內存的第三方DLL,例如用於數據分析。 那沒關系。
一般來說,你應該對你的產品有一種“感覺”。 如果行為大規模改變,那么我會開始調查。
為什么64位版本的程序分配了更多的VirtualMemory?
可能因為.NET不必擔心其他事情。
在32位,只有4 GB的內存,.NET需要確保可以加載其他DLL,可以創建線程等。在64位,8 TB的內存,將始終有1 MB來創建一個新的線。
您提供的鏈接解釋了這個問題:
PrivateMemorySize:
此屬性返回的值表示進程使用的當前內存大小,該內存無法與其他進程共享。
VirtualMemorySize:
此屬性返回的值表示進程使用的當前虛擬內存大小。 操作系統將每個進程的虛擬地址空間映射到物理內存中加載的頁面,或映射到磁盤上虛擬內存頁面文件中存儲的頁面。
因此,第一個通過自己的內存分配來說明應用程序消耗了多少內存,后者告訴它有多少內存映射到它(意味着使用的整個內存空間,包括PrivateMemorySize),包括操作系統和.NET框架庫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.