-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Possible SerialPort memory leak on Raspbian (all Unix?) #55146
Comments
Tagging subscribers to this area: @dotnet/area-system-io Issue DetailsDescriptionWhen using SerialPort.Read(byte[] buffer, int offset, int count) and a TimeoutException occures, the reference for the byte[] buffer used is not released by the underlying SerialStream used by SerialPort. Sample repo: https://github.com/dseeg/SerialPortMemoryLeak Application runs though 20000 iterations of trying to read from a SerialPort and timing out each time. Configuration
Regression?Unknown Datadotnet-counters
dumpheap -stat
gcroot inspection
AnalysisFrom the data I collected using dotnet-counters and dotnet-dump, and inspecting the code for SerialStream.Unix.cs, the byte[] buffer eventually makes its way into a SerialStreamIORequest and loaded into a queue. SerialStreamIORequests should be removed from that queue when they are marked completed. It seems that either this code isn't being reached or IsCompleted is not being set when the cancellation token fires.
|
@dseeg thank you for a very detailed bug report. Would you be interested in sending a PR with a fix? |
@adamsitnik Yes, I would be very interested, but fixing this will be a little bit of a learning experience for me so I'm not sure how long it will take. I've forked the repo and once its finished building (my PC is ancient by todays standards, so its taking a while) and I've had a chance to play with it, I should have a better idea. |
@adamsitnik I was also hit by a memory leak affecting all Unix that turned out to be fixed recently in .net 6: https://github.com/dotnet/runtime/pull/56866/files#diff-efd183ff76a828527dffa9f7370a0459922121146a211b15fd9a4863d4be70d5R1011-R1023 I would have commented in that PR, but it seems to be closed and the issue here is also about leak. That unnanounced change there fixes a leak that happens due to the SerialStreamIORequest being registered to the cancellation token while also holding a reference to it. It was not a rare occurence, since it triggered by passing a cancelation token when using ReadAsync on the stream. Our dump analysis also showed plenty of SerialStreamIORequest and Task like in the current issue, except in our case it was accompanied CancellationTokenSource.CallbackNode instead of CancellationTokenSource. @dseeg the above could explain why SerialStreamIORequest was staying around. I suggest to give it a check against the latest where that PR is in place.
|
reason: dump analysis of the current memory leak points to it being in SerialPort and already fixed in dotnet 6. See dotnet/runtime#55146 (comment)
reason: dump analysis of the current memory leak pointed to it being in SerialPort and already fixed in dotnet 6. See dotnet/runtime#55146 (comment)
@freddyrios Just ran my sample application using 6.0.100-rc.1.21463.6 and I'm still seeing similar results as before:
|
Any progress on this issue, is there still an issue in .NET 6.0.3? |
@npehrsson I don't believe so. We would accept a PR, but otherwise it may be some time (months) before we can give it attention. |
If we had a fix in main, we could potentially discuss backporting to 6.0 as well depending on the risk. |
Description
When using SerialPort.Read(byte[] buffer, int offset, int count) and a TimeoutException occures, the reference for the byte[] buffer used is not released by the underlying SerialStream used by SerialPort.
Sample repo: https://github.com/dseeg/SerialPortMemoryLeak
Application runs though 20000 iterations of trying to read from a SerialPort and timing out each time.
Configuration
Regression?
Unknown
Data
dotnet-counters
dumpheap -stat
gcroot inspection
Analysis
From the data I collected using dotnet-counters and dotnet-dump, and inspecting the code for SerialStream.Unix.cs, the byte[] buffer eventually makes its way into a SerialStreamIORequest and loaded into a queue. SerialStreamIORequests should be removed from that queue when they are marked completed. It seems that either this code isn't being reached or IsCompleted is not being set when the cancellation token fires.
The text was updated successfully, but these errors were encountered: