Skip to content
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

Merged
merged 4 commits into from
Aug 10, 2022

Conversation

bklop
Copy link
Contributor

@bklop bklop commented Apr 14, 2022

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.

…eived on the serial port. Implement a custom SynchronizedQueue to ensure completed SerialStreamIORequests are eligible for GC.
@ghost ghost added the community-contribution Indicates that the PR has been added by a community member label Apr 14, 2022
@ghost
Copy link

ghost commented Apr 14, 2022

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

Issue Details

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.

Author: bklop
Assignees: -
Labels:

area-System.IO

Milestone: -

@dnfadmin
Copy link

dnfadmin commented Apr 14, 2022

CLA assistant check
All CLA requirements met.

@bklop bklop changed the title Fix SerialPort memory leak when requests time and no data is received Fix SerialPort memory leak when requests time out and no data is received Apr 14, 2022
@danmoseley danmoseley requested a review from krwq April 14, 2022 13:31
@kasperk81
Copy link
Contributor

did you notice improvement in cpu usage too? (#2379)

@bklop
Copy link
Contributor Author

bklop commented Apr 25, 2022

did you notice improvement in cpu usage too? (#2379)

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.

@jeffhandley jeffhandley added the needs-author-action An issue or pull request that requires more info or actions from the author. label Jun 24, 2022
@ghost ghost added the no-recent-activity label Jul 9, 2022
@ghost
Copy link

ghost commented Jul 9, 2022

This pull request has been automatically marked no-recent-activity because it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will remove no-recent-activity.

@ghost ghost removed needs-author-action An issue or pull request that requires more info or actions from the author. no-recent-activity labels Jul 19, 2022
@danmoseley
Copy link
Member

@bklop are you planning more work here or are you waiting on review?

@danmoseley
Copy link
Member

@krwq can we merge, or do you plan to do manual tests or something?

@bklop
Copy link
Contributor Author

bklop commented Jul 31, 2022

@bklop are you planning more work here or are you waiting on review?

I was going to make some changes to the queue locking as suggested by @krwq but unfortunately life happened and other things got in the way :(. But I will have some time the coming week so I will try to make these changes ASAP.

@bklop
Copy link
Contributor Author

bklop commented Aug 5, 2022

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 ConditionalFact(nameof(HasOneSerialPort))?

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.

@bklop
Copy link
Contributor Author

bklop commented Aug 8, 2022

@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? :)

Copy link
Member

@krwq krwq left a 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

@krwq
Copy link
Member

krwq commented Aug 9, 2022

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)

@bklop
Copy link
Contributor Author

bklop commented Aug 10, 2022

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?

@krwq krwq merged commit 6da2046 into dotnet:main Aug 10, 2022
@krwq
Copy link
Member

krwq commented Aug 10, 2022

@bklop thanks, try out the nightly package whenever available and validate this fixes your issue:
https://github.com/dotnet/runtime/blob/main/docs/project/dogfooding.md

@ghost ghost locked as resolved and limited conversation to collaborators Sep 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.IO.Ports community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Possible SerialPort memory leak on Raspbian (all Unix?)
6 participants