-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Fix SerialPort memory leak when requests time out and no data is received #68014
Conversation
…eived on the serial port. Implement a custom SynchronizedQueue to ensure completed SerialStreamIORequests are eligible for GC.
Tagging subscribers to this area: @dotnet/area-system-io Issue DetailsFixes #55146 This also replaces the use of ConcurrentQueue with a synchronized Queue to ensure that completed requests (and related data, including any user-supplied buffers) are immediately eligible for GC. This is very important when using SerialPort on resource constrained IoT devices. Since the most common scenario is that of a single client thread calling Read and/or Write and waiting for the result to come back, the coarse locking on the queue should lead to any contention or performance problems in practice.
|
did you notice improvement in cpu usage too? (#2379) |
src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs
Outdated
Show resolved
Hide resolved
I don't think this patch will improve CPU usage in any way (even though I haven't tested it). But I've also had problems with high CPU usage when calling SerialPort.ReadByte() in a loop. Instead I now read directly from the BaseStream and buffer the data read in my own code. This significantly reduced the CPU load. |
This pull request has been automatically marked |
@bklop are you planning more work here or are you waiting on review? |
@krwq can we merge, or do you plan to do manual tests or something? |
I've now pushed my latest changes but I noticed that System.IO.Ports.Tests.SerialStream tests are not run as part of the CI build. I assume this is because of Unfortunately I don't have a serial port on my development machine so I can't run it locally either. Are these type of tests run somewhere else? Otherwise I can run some (informal) tests with a real serial port on a linux IoT device next week. |
@danmoseley / @krwq I tested basic reading/writing with a real serial port on a linux IoT device, works fine. Is there anything more I need to do to get this merged? :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM we can merge once CI is green assuming you've manually done some basic testing. Unfortunately I don't have any setup handy to test this
note that if we want this change to be included in 7.0 release we have to finish testing by this Friday (Aug 12). Later this needs to go through separate approval process and be double merged in 7.0 branch and main (it's not horrible if we miss 7.0 since this is separate nuget package but will definitely be easier if we do) |
It'd be great if this was in the 7.0 release (we currently have a workaround where we dispose and recreate the SerialPort instance to avoid memory leaks on a timeout, but we'd like to get rid of this). Can this be merged, or do you need to do more testing yourself? |
@bklop thanks, try out the nightly package whenever available and validate this fixes your issue: |
Fixes #55146
This also replaces the use of ConcurrentQueue with a synchronized Queue to ensure that completed requests (and related data, including any user-supplied buffers) are immediately eligible for GC. This is very important when using SerialPort on resource constrained IoT devices. Since the most common scenario is that of a single client thread calling Read and/or Write and waiting for the result to come back, the coarse locking on the queue should lead to any contention or performance problems in practice.