我创建了一个简单的测试应用程序,如下所示。
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace PerfMonTest
{
class Program
{
private static List<byte[]> byteArray = new List<byte[]>();
static void Main(string[] args)
{
Console.WriteLine("start now");
Console.ReadLine();
Task t1 = Task.Factory.StartNew(() => { Program.ProcessData(); });
Task.WaitAll(new Task[] { t1});
Console.WriteLine("done ...");
Console.ReadLine();
}
private static byte[] GetData()
{
return new byte[1024 * 1024 * 50];
}
public static void ProcessData()
{
for (int i = 0; i < 50000; i++)
{
byteArray.Add(GetData());
Thread.Sleep(500);
Console.WriteLine("GC Memory consumed:" + Convert.ToString((GC.GetTotalMemory(false) / (1024 * 1024))) + " MB");
}
}
}
}
在此应用程序运行时,我还捕获了两个计数器Private Bytes
和# Bytes in all heaps
。其结果如下:
根据此article,图表应如下所示。
我的问题是,即使所有堆中的字节数几乎没有增加,私有字节也会上升?或者我的代码可能导致Private bytes
计数器中显示的任何本机泄漏?
答案 0 :(得分:2)
问题是你正在使用一种令人难以置信的人为测试,这与现实世界的场景并不匹配。
您正在分配new byte[...]
,但它永远不会超出范围,因此垃圾收集器无法收集它。这就是为什么你为private bytes
获得稳定增长的原因。
同样,byteArray
正在堆上分配,并且不会超出范围。它需要在增长时分配更多空间,但它会以块的形式增长,这就是您在bytes in all heaps
中获得这些步骤的原因。
如果您要定期从列表中删除条目,您会发现private bytes
的循环方式与文章中显示的图表大致相同,不过列表本身(因此也是如此)堆)永远不会在分配的字节中缩小。