⚡️ C#-приём: не привязывай метаданные к объектам через обычный `Dictionary` — иногда нужен `ConditionalWeakTable`.
Допустим, библиотека кеширует данные о типах:
private static readonly Dictionary Cache = new();
В обычном приложении это может годами работать без проблем.
Но если используются plugins, dynamic assemblies или unloadable AssemblyLoadContext, такой словарь способен удерживать Type, а вместе с ним — всю загруженную сборку.
И получить memory leak.
Для таких случаев в .NET есть малоизвестный:
ConditionalWeakTable
Пример:
private static readonly ConditionalWeakTable Cache = new();
static Metadata GetMetadata(Type type)
{
return Cache.GetValue(type, BuildMetadata);
}
Ключ здесь хранится слабо.
Если Type больше нигде не нужен, GC может его собрать, а связанная запись автоматически исчезнет из таблицы.
Это особенно полезно для:
* reflection-кешей;
* proxy/framework-кода;
* source/runtime metadata;
* plugin-систем;
* приложений с AssemblyLoadContext.
🔥 Если видишь:
static Dictionary
или
static ConcurrentDictionary
в коде, который работает с динамически загружаемыми сборками, стоит проверить:
не удерживает ли этот кеш сборки в памяти навсегда?
Иногда правильный ответ — ConditionalWeakTable.
#CSharp #DotNet #Backend #Programming #CLR
Допустим, библиотека кеширует данные о типах:
private static readonly Dictionary Cache = new();
В обычном приложении это может годами работать без проблем.
Но если используются plugins, dynamic assemblies или unloadable AssemblyLoadContext, такой словарь способен удерживать Type, а вместе с ним — всю загруженную сборку.
И получить memory leak.
Для таких случаев в .NET есть малоизвестный:
ConditionalWeakTable
Пример:
private static readonly ConditionalWeakTable Cache = new();
static Metadata GetMetadata(Type type)
{
return Cache.GetValue(type, BuildMetadata);
}
Ключ здесь хранится слабо.
Если Type больше нигде не нужен, GC может его собрать, а связанная запись автоматически исчезнет из таблицы.
Это особенно полезно для:
* reflection-кешей;
* proxy/framework-кода;
* source/runtime metadata;
* plugin-систем;
* приложений с AssemblyLoadContext.
🔥 Если видишь:
static Dictionary
или
static ConcurrentDictionary
в коде, который работает с динамически загружаемыми сборками, стоит проверить:
не удерживает ли этот кеш сборки в памяти навсегда?
Иногда правильный ответ — ConditionalWeakTable.
#CSharp #DotNet #Backend #Programming #CLR