我有一个C#windows服务充当服务器,该服务在内存中保存一些大型(> 8Gb)数据结构,并通过远程处理向客户端公开搜索方法。
平均搜索操作以< 200ms执行,并且该服务最多处理20个请求/秒。
我注意到一些严重的性能下降(> 6000毫秒)定期几秒钟
我最好的猜测是服务器线程不时被gen2垃圾收集停止。
我正在考虑从服务器gc切换到工作站gc并将我的搜索方法包装在此以防止GC在请求期间。
static protected void DoLowLatencyAction(Action action)
{
GCLatencyMode oldMode = GCSettings.LatencyMode;
try
{
GCSettings.LatencyMode = GCLatencyMode.LowLatency;
// perform time-sensitive actions here
action();
}
finally
{
GCSettings.LatencyMode = oldMode;
}
}
这是个好主意吗?
在什么条件下,GC会在低延迟时间段内执行?
注意:我正在使用8核
的x64服务器上运行由于
答案 0 :(得分:9)
之前我没有使用GCLatencyMode
所以无法评论是否使用它是一个好主意。
但是,您确定您使用的是服务器GC吗?默认情况下,Windows服务使用工作站GC。
我之前在Windows服务中遇到过类似的问题,并使用以下方法设置服务器GC模式:
<configuration>
<runtime>
<gcServer enabled="true" />
</runtime>
</configuration>
服务的app.config
文件中的解决了它。
从Tess Ferrandez的博客中读取this post以获取更多详细信息。
答案 1 :(得分:1)
我很惊讶您的搜索方法甚至会触发GC,如果8GB数据结构是静态的(通过添加或删除它没有大量修改),而您所做的就是搜索它,那么您应该尽量避免分配搜索方法中的临时对象(如果可以)。创建对象是触发GC的事情,如果您的数据结构很少被修改,那么将GC全部避开(或尽可能地延迟它)是有意义的。
GCSettings.LowLatency的作用是提示GC做急切的集合,以便在设置LowLatency模式时我们可以避免Gen2集合。这样做的副作用是让GC急于在设置LowLatency模式的区域之外收集,并且可能导致性能降低(在这种情况下,您可以尝试服务器GC模式)。
答案 2 :(得分:0)
这听起来不是一个好主意。在某些时候,GC会忽略你的提示并进行收集。
我相信通过实际分析和优化您的服务,您将获得更好的成功。在服务器运行时运行PerfView(免费,真棒,Microsoft工具)。查看谁拥有麻烦的对象以及特定长期运行的GC事件需要多长时间。