File tree Expand file tree Collapse file tree
src/EFCore/Infrastructure/Internal Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -13,7 +13,16 @@ public class LazyLoaderFactory : ILazyLoaderFactory
1313{
1414 private readonly ICurrentDbContext _currentContext ;
1515 private readonly IDiagnosticsLogger < DbLoggerCategory . Infrastructure > _logger ;
16- private readonly List < ILazyLoader > _loaders = [ ] ;
16+
17+ // Use WeakReference to allow ILazyLoader instances to be GC'ed during enumeration,
18+ // preventing them from being rooted by the factory.
19+ //
20+ // List<WeakReference> is chosen over ConditionalWeakTable to avoid a 30-50%
21+ // performance regression.
22+ //
23+ // While the list does not self-compact, it is explicitly cleared during
24+ // ResetState/Dispose to prevent memory accumulation in pooled contexts.
25+ private readonly List < WeakReference < ILazyLoader > > _loaders = [ ] ;
1726
1827 /// <summary>
1928 /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -38,7 +47,7 @@ public LazyLoaderFactory(
3847 public virtual ILazyLoader Create ( )
3948 {
4049 var loader = new LazyLoader ( _currentContext , _logger ) ;
41- _loaders . Add ( loader ) ;
50+ _loaders . Add ( new WeakReference < ILazyLoader > ( loader ) ) ;
4251 return loader ;
4352 }
4453
@@ -50,9 +59,10 @@ public virtual ILazyLoader Create()
5059 /// </summary>
5160 public void Dispose ( )
5261 {
53- foreach ( var loader in _loaders )
62+ foreach ( var weakReference in _loaders )
5463 {
55- loader . Dispose ( ) ;
64+ if ( weakReference . TryGetTarget ( out var loader ) )
65+ loader . Dispose ( ) ;
5666 }
5767
5868 _loaders . Clear ( ) ;
You can’t perform that action at this time.
0 commit comments