We are noticing a leak when using an EventListener where the runtime seems to be leaking EventWrittenEventArgs on each event invocation. Attached a simple repro which seems to show the leaks on both 2.2 and 3.0. !dumpheap shows that the following objects are not cleaned up even when gcroot doesnt show any roots:
00007ff7d39479b8 407 26048 System.Action
00007ff7d3949150 408 26112 System.Threading.Tasks.Task
00007ff7d39a13f8 6 40392 System.Diagnostics.Tracing.EventSource+EventMetadata[]
00007ff7d3846610 873 54656 System.Object[]
00007ff7d3901d88 641 73734 System.String
00007ff7d39d4838 812 110432 System.Diagnostics.Tracing.EventWrittenEventArgs
Please let me know if you need any further info
ThreadEventsListener.zip
This was tested on 3.0-preview8 on Windows.
cc. @josalem @sywhang
Are you seeing this only on Windows? If possible, could you list out the environments you are seeing this in? I'm specifically looking for architecture, OS family/version, whether the app was containerized, and the output of dotnet --info.
Thanks for reporting the issue @mgodse. Couple questions for you...
We are noticing a leak when using an EventListener where the runtime seems to be leaking EventWrittenEventArgs on each event invocation.
The heap dump alone does not point to a memory leak (at least on its own). Do you mind sharing with us what made you think this is a leak? Are you seeing a constant increase in your managed heap size over time when you use EventListener?
EventWrittenEventArgs is a managed object so it won't be cleaned up unless there is a GC that happens. If you still see these lingering after GCs occur, that means we have a leak. Otherwise this is the expected behavior.
@josalem we believe it repros on Linux too but it has been easy to debug on windows. This is on windows x64, non-containerized app. Here is the dotnet --info:
.NET Core SDK (reflecting any global.json):
Version: 3.0.100-preview8-013656
Commit: 8bf06ffc8d
Runtime Environment:
OS Name: Windows
OS Version: 10.0.14393
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.0.100-preview8-013656\
Host (useful for support):
Version: 3.0.0-preview8-28405-07
Commit: d01b2fb7bc
@sywhang we are noticing that Private Working Set continues to grow within TaskMgr. Also notice the EventArgs not being collected after multiple GCs from what we can see.
Thanks for the details! I've had the repro code running for 59500 iterations (~1 hour) and I haven't seen anything that seems anomalous on my machine. Watching the memory footprint in procexp seems to indicate no growth over that time either (sitting at ~13KB private bytes & 24KB working set). Checking heap diffs in Visual Studio doesn't seem to indicate anything either. I'm going to restart the trial and run it overnight to see if I see anything in the morning.
What was the timescale over which you observed this leak and what was the size of this leak (bytes, KB, MB)? Were you doing any kind of profiling or debugging during execution?
Ok thanks for investigating. I seem to be seeing an increase of about 8Kb every few seconds (based on TaskMgr Private Working Set for the process). Will run some further experiments as well..
It appears that the working set increases for the first 20/30 minutes and then stabilizes. Perhaps this is expected GC behavior ?
Believe we can close this issue assuming the initial increase in working set is expected before plateauing.
I agree, after investigating, I don't think there is a leak here. Thanks for your help!