Posiadamy usługę internetową wykorzystującą WebApi 2, .NET 4.5 na serwerze 2012. Obserwowaliśmy sporadyczne opóźnienia wzrastające o 10-30ms bez uzasadnionego powodu. Udało nam się wyśledzić problematyczny fragment kodu do LOH i GC.Rozległe wykorzystanie LOH powoduje znaczny problem z wydajnością.
Istnieje pewien tekst, który konwertujemy na jego reprezentację bajtów UTF8 (w rzeczywistości biblioteka do serializacji, której używamy). Dopóki tekst jest krótszy niż 85000 bajtów, opóźnienie jest stabilne i krótkie: średnio około 0,2 ms i co najmniej 99%. Po przekroczeniu granicy 85000, średnie opóźnienie wzrasta do ~ 1 ms, podczas gdy 99% przeskakuje do 16-20ms. Profiler pokazuje, że większość czasu spędza się w GC. Aby mieć pewność, jeśli wstawię GC.Collect między iteracjami, zmierzone opóźnienie sięga 0,2 ms.
Mam dwa pytania:
- Skąd opóźnienie pochodzi? O ile rozumiem, LOH nie jest zagęszczony. SOH jest kompaktowany, ale nie wykazuje opóźnienia.
- Czy istnieje praktyczny sposób obejścia tego? Uwaga: nie mogę kontrolować rozmiaru danych i zmniejszać ich.
-
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)]);
}
Czy ta pomoc http://stackoverflow.com/questions/686950/large-object-heap-fragmentation – Sid
nie jest tak naprawdę, to mówi o rozdrobnieniu i moim problemem jest opóźnienie. –