Bug 55721 - Memory leak in HttpListener with SSL
Summary: Memory leak in HttpListener with SSL
Status: NEW
Alias: None
Product: Class Libraries
Classification: Mono
Component: System ()
Version: 4.8.0 (C9)
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Martin Baulig
Depends on:
Reported: 2017-04-28 12:54 UTC by Martin Frydl
Modified: 2017-05-21 12:29 UTC (History)
2 users (show)

Is this bug a regression?: ---
Last known good build:

test case (8.47 KB, application/zip)
2017-04-28 12:54 UTC, Martin Frydl
Memory leak fix (643 bytes, patch)
2017-05-21 12:29 UTC, Martin Frydl

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report for Bug 55721 on GitHub or Developer Community if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: GitHub Markdown or Developer Community HTML
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:

Description Martin Frydl 2017-04-28 12:54:21 UTC
Created attachment 21876 [details]
test case

When HttpListener is used with SSL, the SSL context and other objects remain in memory causing new memory leak for each accepted connection.

Attached is simple test case - Mono application starting HTTP listener server returning "test" on each request. Then there is a client script - it starts the server with heapshot capability and runs 50 request against it. Then it makes heapshot, generates text file using mprof-report and greps the resulting file for Mono.Btls.MonoBtlsContext. This gives following line:

8000         50      160 Mono.Btls.MonoBtlsContext

So there are 50 instances of context after 50 requests. You can update the script to increase number of connections (iters=50). The test case zip contains also the full text report. The script needs curl and netcat.
Comment 1 Martin Frydl 2017-05-21 12:28:46 UTC
The problem is caused by HttpConnection not closing the underlying stream. It just closes the socket but leaves the stream alone. Normally, this is not a problem because it does not keep any system resources and gets garbage collected later when all references are lost.

However, when SSL is used, the stream (MonoBtlsStream) creates various BTLS classes like MonoBtlsContext, MonoBtlsX509Store etc. The problem with these classes is that some of them cooperate with native code and so they allocate GCHandles to themselves to pass to the native code. And these handles are released in Close() methods. So when Close() is not called, all the objects remain in memory even if all references to stream are lost. Because they are effectively not - there are still those GCHandles keeping everything in memory.

I've attached a patch which closes the stream in HttpConnection and thus solves the memory leak.
Comment 2 Martin Frydl 2017-05-21 12:29:37 UTC
Created attachment 22331 [details]
Memory leak fix