我正在尝试使用.Net AppDomain Class的MonitoringSurvivedMemorySize属性。
只有问题我无法看到我的应用程序从此属性获得的值如何符合msdn上给出的属性的描述。
我观察到的差异包括Property返回一个我知道太低的值,因为返回的值与前一个调用返回的值不同,并且在这两个调用之间,AppDomain引用的内存量从未如此低值作为新的返回值。
我搜索了SO,google和connect.microsoft.com以进行“AppDomain Monitoring”,但找不到任何与上述特定问题相关的内容。
为了确保这不会对我的应用程序的其他部分做任何事情,我使用以下代码创建了一个新的ConsoleApplication:
class Program
{
static void Main(string[] args)
{
Console.WindowWidth = 133;
AppDomain.MonitoringIsEnabled = true;
var Queue = new Queue<byte[]>();
var BlockSize = (int)1e+6;
var ToggleAllocation = true;
while (true)
{
if (Console.KeyAvailable)
{
var Input = Console.ReadKey(true);
if (Input.Key == ConsoleKey.Escape)
{
break;
}
if (Input.Key == ConsoleKey.C)
{
GC.Collect();
Console.WriteLine("Collect");
}
ToggleAllocation = !ToggleAllocation;
}
Thread.Sleep(100);
if (!ToggleAllocation)
{
continue;
}
Queue.Enqueue(new byte[BlockSize]);
while (100 < Queue.Count)
{
Queue.Dequeue();
}
var ExpectedLowerBound = Queue.Count * BlockSize;
var MonitoringSurvivedMemorySize = AppDomain.CurrentDomain.MonitoringSurvivedMemorySize;
var MonitoringTotalAllocatedMemorySize = AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize;
Console.WriteLine(
"Queue.Count=" + Queue.Count.ToString() +
", SurvivedMemorySize=" + MonitoringSurvivedMemorySize.ToString() +
", TotalAllocatedMemorySize=" + MonitoringTotalAllocatedMemorySize.ToString() +
", ExpectedLowerBound=" + ExpectedLowerBound.ToString());
}
}
}
此函数只是不时地分配一些内存以确保gc最终会发生并打印出MonitoringSurvivedMemorySize接收的值。
为了确保问题不是由某些调试器“功能”引起的,我将项目切换到默认版本配置并从资源管理器运行该程序。
当我运行这个程序时,MonitoringSurvivedMemorySize在某些迭代中返回0,然后经过一些迭代(我假设在第一个gc之后)有一个更高的值满足我的期望。但经过一些迭代后,返回值会跳回零。它还会返回不同于零但从远到低的值。
我将Target框架设置为“.NET Framework 4 Client Profile”
我做错了什么?
你能复制吗?
答案 0 :(得分:0)
根据文档(来自您提供的链接),您应该只在完整阻止收集后才能获得更新的统计信息。尝试在测试平台中添加对GC.Collect的调用。
答案 1 :(得分:0)
我使用.NET Framework 4.5遇到了同样的问题,并将其作为错误提交给microsoft。 现在,他们提供了一个答案并修复了它(对于.NET Framework 4.5)
以下引用源自上面链接的页面:
这是一个文档错误,而不是GC错误。文档 在 http://msdn.microsoft.com/library/system.appdomain.monitoringsurvivedmemorysize(v=vs.110).aspx 被修改为:
“每次垃圾回收都会更新统计信息。但是, 只有在完全阻塞之后,它们才能保证准确 采集;也就是说,包含所有世代的集合 在收集发生时停止应用程序。例如, GC.Collect()方法重载执行完整的阻塞集合。 (并发收集发生在后台,不会阻止 申请。)“
- Ron Petrusha公共语言运行时用户教育Microsoft Corporation
由于观察到的响应时间很长,我将不再要求在Microsoft 4.0上澄清.NET 4.0,而是高声宣布这是OP的有效答案。