Минутка хардкора-2: Alois Kraus: что с памятью твоей?
От: Sinix  
Дата: 04.10.16 07:44
Оценка: 19 (3) +1
Продолжаем начатое
Автор: Sinix
Дата: 15.09.16
.

На этот раз — Windows 10 Memory Compression And More от Alois Kraus.

Название имхо неудачное, т.к. этому самому And More посвящена бОльшая (и самая интересная) часть статьи, "In memories of SetProcessWorkingSetSize" подошло бы лучше. Почему так и просто освежить память про "что все эти столбцы в TaskManager значат???" — тынц по ссылке, если ещё не.

Статья не затрагивает ничего специфичного для шарпа / CLR, так что слегка неформат. Но поправить легко

          Alloc 1 mb:     0ms, ips:       1 032 062 992,13 | Mem:     1 032,05 kb, GC 0/1/2: 0/0/0 => 131072
          Alloc 1 gb:     0ms, ips:     171 021 569 826,71 | Mem: 1 048 584,05 kb, GC 0/1/2: 0/0/0 => 134217728
          Alloc 4 gb:     3ms, ips:     141 897 954 803,75 | Mem: 4 194 312,05 kb, GC 0/1/2: 0/0/0 => 536870912
Done.

  Где подвох?
using System;
using System.Diagnostics;

static class Program
{
    static void Main(string[] args)
    {
        Console.WindowWidth = 120;

        long[] data = null;
        Measure("Alloc 1 mb", () =>
        {
            data = new long[1024 * 1024 / 8];
            return data.Length;
        });
        GC.KeepAlive(data);

        Measure("Alloc 1 gb", () =>
        {
            data = new long[1024 * 1024 * 1024 / 8];
            return data.Length;
        });
        GC.KeepAlive(data);

        // run as x64; set <gcAllowVeryLargeObjects> !!!
        Measure("Alloc 4 gb", () =>
        {
            data = new long[1024 * 1024 * 1024 / 2];
            return data.Length;
        });
        GC.KeepAlive(data);

        Console.WriteLine("Done.");
        Console.ReadKey();
    }


    static void Measure(string name, Func<long> callback)
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();

        var mem = GC.GetTotalMemory(true);
        var gc00 = GC.CollectionCount(0);
        var gc01 = GC.CollectionCount(1);
        var gc02 = GC.CollectionCount(2);

        var sw = Stopwatch.StartNew();
        var result = callback();
        sw.Stop();

        var mem2 = GC.GetTotalMemory(false);
        var gc10 = GC.CollectionCount(0);
        var gc11 = GC.CollectionCount(1);
        var gc12 = GC.CollectionCount(2);

        var memDelta = (mem2 - mem) / 1024.0;
        var gcDelta0 = gc10 - gc00;
        var gcDelta1 = gc11 - gc01;
        var gcDelta2 = gc12 - gc02;

        Console.WriteLine(
            "{0,20}: {1,5}ms, ips: {2,22:N} | Mem: {3,9:N2} kb, GC 0/1/2: {4}/{5}/{6} => {7,6}",
            name, sw.ElapsedMilliseconds, result / sw.Elapsed.TotalSeconds, memDelta, gcDelta0, gcDelta1, gcDelta2, result);
    }
}

app.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <runtime>
        <gcAllowVeryLargeObjects enabled="true" />
    </runtime>
</configuration>


P.S. старый блог того же автора. Строго рекомендую всем, кто собирается правильно готовить WPA.
Для затравки: Is This A CPU Bug? Why Is The First Start Of An Application Slow?

P.P.S. Аналог для managed-процессов: perfView. Теперь и с возможностью встроить самодиагностику в приложение.

UPD Продолжение сериала. На этот раз действительно про Windows 10 Memory Compression.
Отредактировано 09.01.2017 11:52 Sinix . Предыдущая версия . Еще …
Отредактировано 10.10.2016 13:06 Sinix . Предыдущая версия .
Отредактировано 04.10.2016 8:14 Sinix . Предыдущая версия .
минутка хардкора
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.