我们在 Server 2012 上有一个使用 WebApi 2 和 .NET 4.5 的 Web 服务。我们发现延迟偶尔会增加 10-30 毫秒,没有充分的理由。我们能够将有问题的代码段追踪到 LOH 和 GC。
我们将一些文本转换为其 UTF8 字节表示(实际上,我们使用的序列化库就是这样做的)。只要文本短于 85000 字节,延迟就稳定且短:平均约为 0.2 毫秒,达到 99%。一旦超过 85000 边界,平均延迟就会增加到约 1 毫秒,而 99% 会跳到 16-20 毫秒。Profiler 显示大部分时间都花在了 GC 上。可以肯定的是,如果我在迭代之间放置 GC.Collect,测得的延迟会回到 0.2 毫秒。
我有两个问题:
- 延迟从何而来?据我了解,LOH 没有被压缩。SOH 正在被压缩,但没有显示延迟。
- 有没有一种实用的方法来解决这个问题?请注意,我无法控制数据的大小并使其更小。
--
public void PerfTestMeasureGetBytes()
{
var text = File.ReadAllText(@"C:\Temp\ContactsModelsInferences.txt");
var smallText = text.Substring(0, 85000 + 100);
int count = 1000;
List<double> latencies = new List<double>(count);
for (int i = 0; i < count; i++)
{
Stopwatch sw = new Stopwatch();
sw.Start();
var bytes = Encoding.UTF8.GetBytes(smallText);
sw.Stop();
latencies.Add(sw.Elapsed.TotalMilliseconds);
//GC.Collect(2, GCCollectionMode.Default, true);
}
latencies.Sort();
Console.WriteLine("Average: {0}", latencies.Average());
Console.WriteLine("99%: {0}", latencies[(int)(latencies.Count * 0.99)]);
}