【发布时间】:2019-01-30 13:43:39
【问题描述】:
我创建了一个简单的测试应用程序,它使用二进制数组分配 100mb。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace VirtualMemoryUsage
{
class Program
{
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"IsServerGC = {System.Runtime.GCSettings.IsServerGC.ToString()}");
const int tenMegabyte = 1024 * 1024 * 10;
long allocatedMemory = 0;
List<byte[]> memory = new List<byte[]>();
for (int i = 0; i < 10; i++)
{
//alloc 10 mb memory
memory.Add(new byte[tenMegabyte]);
allocatedMemory += tenMegabyte;
}
sb.AppendLine($"Allocated memory: {PrettifyByte(allocatedMemory)}");
sb.AppendLine($"VirtualMemorySize64: {PrettifyByte(Process.GetCurrentProcess().VirtualMemorySize64)}");
sb.AppendLine($"PrivateMemorySize64: {PrettifyByte(Process.GetCurrentProcess().PrivateMemorySize64)}");
sb.AppendLine();
Console.WriteLine(sb.ToString());
Console.ReadLine();
}
private static object PrettifyByte(long allocatedMemory)
{
string[] sizes = { "B", "KB", "MB", "GB", "TB" };
int order = 0;
while (allocatedMemory >= 1024 && order < sizes.Length - 1)
{
order++;
allocatedMemory = allocatedMemory / 1024;
}
return $"{allocatedMemory:0.##} {sizes[order]}";
}
}
}
注意:对于这个测试,在 app.config 中将 gcserver 设置为 true 很重要
<runtime>
<gcServer enabled="true"/>
</runtime>
这将显示进程分配的 PrivateMemorySize64 和 VirtualMemorySize64 的数量。
虽然 PrivateMemorySize64 在不同的计算机上保持相似,但 VirtualMemorySize64 变化很大。
在分配相同数量的内存时,VirtualMemorySize64 出现这种差异的原因是什么?有这方面的文档吗?
【问题讨论】:
-
当系统内存不足时,垃圾收集器触发并释放繁忙的。只要有足够的内存,垃圾收集器就会休眠。
-
潜在原因:因为它可用。官方文档:不太可能,因为 GC 内部可能会发生变化。您是否在打开其他几个程序时交叉检查数字是否发生变化,从而导致可用 RAM 量减少?另外:该内存是保留还是已提交?保留内存非常快。提交内存很慢。
-
@AlexanderPetrov:小心,GC 可能会释放内存,但可能不会返回操作系统,只是内部的 .NET。如果对 Manuel 的观察导致了单个 VirtualAlloc 内存块,它永远无法将其归还。