アンマネージメモリと GC (検証)

アンマネージメモリと GC - 気楽に諸々 を検証してみた!


・マネージメモリ確保

static void Main()
{
    const int size = 200 * 1024 * 1024;
    byte[] managedBinary = new byte[size];
    for (int i = 0; i < size; i++)
    {
        managedBinary[i] = 0;
    }

    GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized);
    Console.WriteLine(0 < GC.CollectionCount(0));

    GC.KeepAlive(managedBinary);
}

出力 : True


GC にプレッシャー

static void Main()
{
    const int size = 200 * 1024 * 1024;
    GC.AddMemoryPressure(size);

    GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized);
    Console.WriteLine(0 < GC.CollectionCount(0));

    GC.RemoveMemoryPressure(size);
}

出力 : True


・アンマネージメモリ確保

unsafe static void Main()
{
    const int size = 200 * 1024 * 1024;
    byte* unmanagedBinary = (byte*)Marshal.AllocHGlobal(size);
    for (int i = 0; i < size; i++)
    {
        unmanagedBinary[i] = 0;
    }

    GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized);
    Console.WriteLine(0 < GC.CollectionCount(0));

    Marshal.FreeHGlobal((IntPtr)unmanagedBinary);
}

出力 : False


・アンマネージメモリ確保 + GC にプレッシャー

unsafe static void Main()
{
    const int size = 200 * 1024 * 1024;
    byte* unmanagedBinary = (byte*)Marshal.AllocHGlobal(size);
    GC.AddMemoryPressure(size);
    for (int i = 0; i < size; i++)
    {
        unmanagedBinary[i] = 0;
    }

    GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized);
    Console.WriteLine(0 < GC.CollectionCount(0));

    Marshal.FreeHGlobal((IntPtr)unmanagedBinary);
    GC.RemoveMemoryPressure(size);
}

出力 : True


[結論]
Marshal.AllocHGlobal でアンマネージメモリに大容量データを確保したら GC.AddMemoryPressure で GC に報告してやる必要があるお><