GC принудительно работает с малыми изображениями (< = 4k пиксельных данных)?

Счетчик производительности «# Industed GC» (который должен оставаться на нулевом уровне в совершенном приложении) быстро увеличивается при обработке небольших файлов (< = 32x32) через WriteureBitmap .

Хотя это не является существенным узким местом в небольшом приложении, это становится очень серьезной проблемой (замораживание приложения на 99,75% «% времени в GC» в течение нескольких секунд на каждом шаге), когда в памяти находится несколько тысяч объектов (например, контекст EntityFramework , загруженный множеством сущностей и взаимосвязей).

Синтетический тест:

var objectCountPressure = (
    from x in Enumerable.Range(65, 26)
    let root = new DirectoryInfo((char)x + ":\\")
    let subs = 
        from y in Enumerable.Range(0, 100 * IntPtr.Size)
        let sub =new {DI = new DirectoryInfo(Path.Combine(root.FullName, "sub" + y)), Parent = root}
        let files = from z in Enumerable.Range(0, 400) select new {FI = new FileInfo(Path.Combine(sub.DI.FullName, "file" + z)), Parent = sub}
        select new {sub, files = files.ToList()}
    select new {root, subs = subs.ToList()}
    ).ToList();

const int Size = 32;
Action<int> handler = threadnr => {
    Console.WriteLine(threadnr + " => " + Thread.CurrentThread.ManagedThreadId);
    for (int i = 0; i < 10000; i++)    {
        var wb = new WriteableBitmap(Size, Size, 96, 96, PixelFormats.Bgra32, null);
        wb.Lock();
        var stride = wb.BackBufferStride;
        var blocks = stride / sizeof(int);
        unsafe {
            var row = (byte*)wb.BackBuffer;
            for (int y = 0; y < wb.PixelHeight; y++, row += stride)
            {
                var start = (int*)row;
                for (int x = 0; x < blocks; x++, start++)
                    *start = i;
            }
        }
        wb.Unlock();
        wb.Freeze();     }
};
var sw = Stopwatch.StartNew();
Console.WriteLine("start: {0:n3} ms", sw.Elapsed.TotalMilliseconds);
Parallel.For(0, Environment.ProcessorCount, new ParallelOptions{MaxDegreeOfParallelism = Environment.ProcessorCount}, handler);
Console.WriteLine("stop : {0:n2} s", sw.Elapsed.TotalSeconds);

GC.KeepAlive(objectCountPressure);

Я могу запустить этот тест, используя « const int Size = 48 » десяток раз: он всегда возвращается в ~ 1 .5s и «# Industed GC» иногда увеличивается на 1 или 2.

Когда я меняю « const int Size = 48 » на « const int Size = 32 », происходит что-то очень плохое: «# Industed GC» увеличивается на 10 в секунду, и общая продолжительность выполнения теперь больше минуты: ~ 80! [Протестировано на Win7x64 Core-i7-2600 с помощью 8GB RAM//.NET 4,0,30319,237]

WTF!?

Либо у Рамки очень плохая ошибка, либо я делаю что-то совершенно неправильно.

BTW :
Я обошел эту проблему, не выполняя обработку изображений, а просто используя подсказку, содержащую изображение для некоторых сущностей базы данных через DataTemplate: Это работало хорошо (быстро), хотя в оперативной памяти не было очень много объектов, но когда существовало несколько миллионов других объектов (совершенно не связанных), то отображение всплывающей подсказки всегда задерживалось на несколько секунд, в то время как все остальное просто работало нормально.

-121--942343- Как обращаться с нулевыми значениями при сериализации массивов с помощью protobuf-net? Следующая инструкция завершается неуспешно с "" "" "" "" ": TypeModel.Create ()" ".DeepClone (новый ряд" "[1]); Анализ исходного кода показывает, что исключение вызывается специально, подразумевая, что null...

Следующая инструкция завершается неуспешно с StartReferureException :

TypeModel.Create().DeepClone(new string[1]);

Проверка исходного кода показывает, что исключение инициируется специально, подразумевая, что значения null в массиве нарушают спецификацию буферов протокола (имеет смысл, null не является повторением какого-либо значения).

Хорошо, спецификация правильная, но что нам делать, если в коллекции все еще есть нулевое значение? Есть ли решение, кроме того, чтобы убедиться, что значения null никогда не ползуют в наши коллекции?

Спасибо.

7
задан mark 7 September 2011 в 09:45
поделиться