Here's a test:
WeakReference ref1;
WeakReference ref2;
TestRepositoryEntitiesContainer context;
int i = 0;
using (context = GetContext<TestRepositoryEntitiesContainer>())
{
context.ObjectMaterialized += (o, s) => i++;
var item = context.SomeEntities.Where(e => e.SomePropertyToLookupOn == "some property").First();
context.Detach(item);
ref1 = new WeakReference(item);
var newItem = new SomeEntity {SomePropertyToLookupOn = "another value"};
context.SomeEntities.AddObject(newItem);
ref2 = new WeakReference(newItem);
context.SaveChanges();
context.SomeEntities.Detach(newItem);
newItem = null;
item = null;
}
context = null;
GC.Collect();
Assert.IsFalse(r开发者_高级运维ef1.IsAlive);
Assert.IsFalse(ref2.IsAlive);
First assert passes, second fails... I hope I'm missing something, it is late... But it appears that detaching a fetched item will actually release all handles on the object letting it be collected. However, for new objects something keeps a pointer and creates a memory leak.
NB - this is EF 4.0
Anyone seen this before and worked around it?
Thanks for your help!
Tom
Did you try running this with optimizations (i.e. Release mode) and without a debugger attached? The JIT compiler may be artificially extending the lifetime of the newItem object until the end of the method.
I was able to reproduce the issue when running without optimizations, but not with optimizations.
精彩评论