我负责管理许多用户在不同硬件上运行的WPF桌面应用程序。多个线程不断地通过大量数据流失。
启用.NET Framework 4.5 Background server garbage collection已经显示出显着的性能改进,但这需要花费更多的内存和不同的CPU使用模式。对于功能较弱的用户来说,这是一个潜在的问题,所以我想给那些最有利于选择加入服务器GC的用户,而不是强迫每个人使用。
到目前为止,我发现启用此功能的唯一方法是App.Config:
<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
但是,大多数用户无权编辑此内容,因为该应用程序位于“程序文件”中,而且他们不是本地管理员。我理想的情况是一个友好的措辞选项,可以在启用服务器GC的情况下重新启动应用程序并记住他们的选择。
所以我的问题是:有没有人知道应用此设置的其他任何方式?
我知道它可能是一厢情愿的想法 - 但理想情况下是运行时的动态,或者可能是在流程上下文中设置的命令行参数或环境变量。 CoreCLR中存在complus_gcServer env variable的提示。
我已经阅读了有关全局系统设置的信息,可以在计算机上启用此设置,但我不想冒险影响任何其他应用并导致其他不利影响,我只希望这适用于我的应用。
作为最后的手段,我可以使用不同的配置文件和启动器部署两个EXE副本来选择要运行的正确版本,但这看起来很极端。
感谢阅读,欢迎任何想法!
答案 0 :(得分:1)
这是另一个建议。完成后保持服务器GC启用。然后基于用户定义的设置强制GC运行,如果应用程序内存超过您确定为临界级别的特定阈值。
请注意,如果您遵循此路径,则有效地说明您对CLR执行垃圾收集的时间有了更好的了解。通常情况下,我发现CLR本身比我们干预时更好。
检查内存使用情况并在所有代或指定代中运行GC的代码
if (Math.Abs(DateTime.Now.Subtract(MemUsageLastCheckTime).TotalMinutes) > 5d)
{
long UsedMemory;
//UsedMemory = GC.GetTotalMemory(false); // Not as reliable
UsedMemory = System.Diagnostics.Process.GetCurrentProcess().PagedMemorySize64;
if (UsedMemory > 1073741824) // One GB in bytes 1 X 1024 X 1024 X 1024
{
GC.Collect(); // Collect all generations
//GC.Collect(2,GCCollectionMode.Forced);; Or collect a specific generation and force it to run now
}
MemUsageLastCheckTime = DateTime.Now;
}