-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Query: Entities not being released due to leak in query caching #6737
Comments
Are you running in release mode? And are you sure that garbage collection has run? |
I was debugging and I'm 90% certain as other objects (non ef) are released when I force a collection. Sent from my iPhone On 10 Oct 2016, at 19:46, Rowan Miller <[email protected]mailto:[email protected]> wrote: Are you running in release mode? And are you sure that garbage collection has run? You are receiving this because you authored the thread. All electronic mail to, from, or within the Telford & Wrekin Council may be the Telford & Wrekin Council may monitor email traffic data and also the content of email in conjunction with the relevant policies. |
A few data points on this in case it helps:
A more reliable way to tell if the entity is still in memory is to look after the |
Hi, Thanks for the comments. • Unfortunately AsNoTracking() does not help me, as I have found that by using it, the entity relationships are not loaded automatically. Rightly or wrongly I have found that by doing the following: class TableA { class TableB{ Context.TableA.ToList(); Significantly out performs Context.TableB.Include(row => row.TABLEA). AsNoTracking().ToList(); On my more complex model, I also got out of memory exceptions using the AsNoTracking() technique, where I didn’t get anywhere close using the first method. • I first noticed this when I ran my app in release mode. As you may gather I am loading a large amount of data for a year, If I want to load another years data in, I reset all my objects back to null and restart the load process, I noticed that the amount of memory being used was increasing rather than staying at a constant (as best as) level. Eventually, by keep loading data from 1 year to the next, Out Of Memory exceptions are thrown.. • I looked at the memory, when the USING had completed, then when Test() had completed and then after a system.gc.collect() completed. Each time, the objects were still in memory. I have attached an sample project hopefully demonstrating my issue. You will need to add the Framework and adjust the DB Connection. When the Main Method (EFTest) or MainWindow Constructor (WPFApplication) has got to the end, there are multiples of the same rows from TableA & TableB still in memory. It's probably my complete misunderstanding of the garbage collection Hope this makes sense |
Before we get someone to dig into this, I just want to double check that this isn't because the entities are databound to a form? If there is no databinding, then we'll get someone to look at it. |
The data items are not bound |
Thanks, we'll take a look at it. |
This seems to be a leak in query caching, which is keeping references to the context. There may be other paths, but the one I have been able to trace is this:
Marking the bug for re-triage. |
- Fixed two places where compiled queries were inadvertantly holding onto scoped QueryCompiler state: 1) The query expression used in the compiled query cache key via EntityQueryable<> constant expressions. 2) The compiled query delegate, via a capturing closure in QueryCompiler itself.
- Fixed two places where compiled queries were inadvertently holding onto scoped QueryCompiler state: 1) The query expression used in the compiled query cache key via EntityQueryable<> constant expressions. 2) The compiled query delegate, via a capturing closure in QueryCompiler itself.
I can confirm with @ajcvickers that the issue is still happening. This seems like a decent bug because it is going to bogart resources/DTUs on Azure until this is patched. |
@anpete just confirm, is the bug fix included in 1.1.0-preview1? |
No, didn't make it. |
@anpete Is there a time frame for the patch release and if there is a work around? Is this an issue with IDisposable or just the implementation with EF? |
@schwietertj The problem was with EF. You can see the details in this PR #6819 I think there may be a workaround, which is to Detach all entities from the leaked DbContext. I.e. The context instance that was used to initially execute the query. cc @ajcvickers who should be able to confirm. |
@schwietertj @anpete That should work to release the vast majority of the memory. |
@ajcvickers @anpete Thank you for pointing me in a good direction. I will try it out at work tomorrow and let you know what I find. |
@ajcvickers @anpete I believe it worked when a variable was declared and set to the entity. In the following instance there would not be an entity to detach and thus a connection will still persist.
I am thinking I will have to wait for the patch to be released and monitor production. The only other work around I can think of would be to set up a service that queries azure for any connection that has been quiet for 30 seconds and kill it. |
@schwietertj You can enumerate all of the entities via DbContext.ChangeTracker.Entries() |
@schwietertj are you saying that you are seeing database connections leaked? The original issue that was reported here and that was fixed and for which the workaround applies is about a memory leak and not related to database connections. |
@divega Very good point. I have experienced both memory leaks and connections that should be disposed that are not being disposed of in the application. After a request is made in the mvc project, I can look at the activity monitor in ssms and still see an active process. The process should not be active since the db context has been disposed. I originally thought it was due to DI the db context. I removed the injection and refactored with the "using" statement. Please correct me if I am wrong but the database connection should be closed after the using block has been executed. If need be I can open a new issue if it is deemed to be a separate issue than this one. |
@schwietertj It could be #6581 which causes some connections to be left open. It has been fixed for 1.0.2 (not yet released) and in 1.1.0-preview1. My understanding is that the workarounds for it are (a) enable MARS in the connection string and (b) avoid using If you think that is not what you are hitting then yes please create a new issue. |
@divega I just tried enabling MARS and the connection count increased 8 fold per active user. We also have to use includes since lazy loading isn't implemented. Is there an ETA on the 1.0.2 release? |
This patch is approved, please ensure it is merged into the correct branch and building as part of the patch train. |
- Fixed two places where compiled queries were inadvertently holding onto scoped QueryCompiler state: 1) The query expression used in the compiled query cache key via EntityQueryable<> constant expressions. 2) The compiled query delegate, via a capturing closure in QueryCompiler itself.
- Fixed two places where compiled queries were inadvertently holding onto scoped QueryCompiler state: 1) The query expression used in the compiled query cache key via EntityQueryable<> constant expressions. 2) The compiled query delegate, via a capturing closure in QueryCompiler itself.
@rowanmiller I know this is an old thread, but about halfway through you ask:
Does running in debug mode cause some sort of known memory leak? I'm trying to track down an EF memory leak and am grasping at straws. |
@joshmouch No known issue like that, |
Apologies if this has been mentioned before:
The problem I am seeing, is that entities are still being held in memory, even after the Context has been disposed.
I have tried the following:
When you view the memory heap after the method Test has completed, ExampleTable rows are still held in memory.
The text was updated successfully, but these errors were encountered: