Skip to content

TypeDescriptor caching blocks unloading of code which uses it from unloadable load context #30656

@vitek-karas

Description

@vitek-karas

The implementation of TypeDescription and TypeConverter uses internal caches which hold strong references to the Type object. These remain even after the descriptors and converters are released by the user code.

If these types come from collectible assemblies (either dynamic types, or custom unloadable AssemblyLoadContext), this prevents unloading of such assembly.

This is exaggerated by the fact that TypeConverter is used by Newtonsoft.Json during serilization or deserialization of JSON. This is VERY common in user code. This effectively means that any app which uses plugins and wants to be able to unload the plugins successfully would have to prevent all such plugins from using Newtonsoft.Json serialization on objects from the plugin.

This is basically a feature ask to modify all the internal caches in TypeDescriptor/TypeConverter implementation to be based on weak references, so that it's possible to collect the types.

Customer issue which ran into this, with detailed analysis of what happens: https://github.com/dotnet/coreclr/issues/26271

It was possible to workaround in this case by loading the ComponentModel assemblies many times into separate ALCs, but that comes with large performance penalty and is not an obvious solution to the problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions