You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ClassLoader::ComputeLoaderModuleWorker uses a LoaderAllocator creation number to determine the latest LoaderAllocator to place a class in. However the method does not account the number of the type definition itself when calculating the latest number and this can lead into a situation when the generic instance is put into an older LoaderAllocator.
E.g. if we have type ClassA from AssemblyLoadContext A with number 2 and type ClassB from AssemblyLoadContext B with number 5 the resulting loader allocator for the type ClassB would correspond to AssemblyLoadContext A with creation number 2. If ClassB contains a static, such static would be then placed under the LoaderAllocator A, preventing AssemblyLoadContext B from unloading unless A is unloaded.
Reproduction Steps
Create 2 classes in 2 different assemblies
Assembly A
public class ClassA
{
}
Assembly B
public class ClassB<T>
{
public static T instance = new T();
}
Load A.dll into a collectible AssemblyLoadContext A.
Load B.dll into a collectible AssemblyLoadContext B.
Instantiate type ClassB<ClassA>.
Ensure instance is not referenced and unload AssemblyLoadContext B.
alexey-zakharov
changed the title
LoaderAllocator selection logic for a generic type instance does not account for a LoaderAllocator of a type itself
LoaderAllocator selection logic for a generic type instance does not account for a LoaderAllocator of type itself
Jan 20, 2025
@alexey-zakharov this looks like a good idea. Would you like to open a PR with your change against the dotnet/runtime repo? I think it is a nice upgrade to the existing logic, and I would happily approve it.
@alexey-zakharov this looks like a good idea. Would you like to open a PR with your change against the dotnet/runtime repo? I think it is a nice upgrade to the existing logic, and I would happily approve it.
awesome, thanks @davidwrighton! I'm happy to make a PR - this is it with small cleanups #111706
Description
ClassLoader::ComputeLoaderModuleWorker
uses a LoaderAllocator creation number to determine the latest LoaderAllocator to place a class in. However the method does not account the number of the type definition itself when calculating the latest number and this can lead into a situation when the generic instance is put into an older LoaderAllocator.E.g. if we have type
ClassA
from AssemblyLoadContextA
with number 2 and typeClassB
from AssemblyLoadContextB
with number 5 the resulting loader allocator for the typeClassB
would correspond to AssemblyLoadContextA
with creation number 2. IfClassB
contains a static, such static would be then placed under the LoaderAllocatorA
, preventing AssemblyLoadContextB
from unloading unlessA
is unloaded.Reproduction Steps
Assembly A
Assembly B
A.dll
into a collectible AssemblyLoadContextA
.B.dll
into a collectible AssemblyLoadContextB
.ClassB<ClassA>
.B
.Expected behavior
AssemblyLoadContext
B
is unloaded successfullyActual behavior
AssemblyLoadContext
B
is not unloadedRegression?
No
Known Workarounds
No response
Configuration
No response
Other information
The following change seem to fix the issue - Unity-Technologies#279
The text was updated successfully, but these errors were encountered: