我有以下测试,我在工作站模式和服务器模式下运行CLR垃圾收集器。在服务器模式结束时,我最终得到520 MB私有字节,在工作站模式下,我最终只有50 MB。这是windbg的输出结果:
!eeheap
...
...
GC Heap Size: Size: 0x65ccac8 (106744520) bytes.
!address -summary
...
...
--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE 53 7ffb`ae203000 ( 127.983 Tb) 99.99%
MEM_RESERVE 94 4`31617000 ( 16.772 Gb) 97.06% 0.01%
MEM_COMMIT
336 0`207d6000(519.836 Mb)2.94%0.00%
尽管在执行结束时我强制使用完整的GC,但导致这种差异的原因是什么呢?
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static int N = 25 * 1000 * 1000; // Execute allocations in a loop 25 million times
static int Clear = 1000 * 1000; // Clear list after every 1 million allocations to give GC 25 chances to clear things up
static void Main(string[] args)
{
// do some warmup
AllocateRefContainer();
GC.Collect();
GC.Collect();
var sw = Stopwatch.StartNew();
AllocateRefContainer();
sw.Stop();
Console.WriteLine("RefContainer Allocation {0:F2}s, {1:N0} Allocs/s", sw.Elapsed.TotalSeconds, N / sw.Elapsed.TotalSeconds);
GC.Collect();
GC.Collect(2, GCCollectionMode.Forced, true);
Thread.Sleep(1000);
Console.WriteLine("PooledRefContainer Allocation {0:F2}s, {1:N0} Allocs/s", sw.Elapsed.TotalSeconds, N / sw.Elapsed.TotalSeconds);
Console.WriteLine("Private Bytes: {0:N0} MB", Process.GetCurrentProcess().PrivateMemorySize64 / (1024 * 1024));
Console.ReadLine();
}
class ReferenceContainer // Class with one object reference
{
public ReferenceContainer Obj;
}
static List<ReferenceContainer> RContainer = new List<ReferenceContainer>();
static void AllocateRefContainer()
{
var container = RContainer;
for (int i = 0; i < N; i++)
{
container.Add(new ReferenceContainer());
Calculate();
if (i % Clear == 0)
{
container.Clear();
}
}
}
// Simulate some CPU only calculation
static void Calculate()
{
long lret = 0;
for (int i = 0; i < 100; i++)
{
lret++;
}
}
}
答案 0 :(得分:0)
服务器模式为每个逻辑处理器核心运行1个GC线程。该线程被分配了自己的工作集。因此,如果你有8个核心,那么开销大约是8倍。 GC也是非确定性的,因此您无法可靠地评估内存使用情况,因为报告的字节是应用程序的保留,而不是那些使用的。服务器GC更具侵略性,可以保留更多字节。
See this MSDN article了解更多信息。