Bug 31500 - NSDirectoryEnumerator memory issue
Summary: NSDirectoryEnumerator memory issue
Alias: None
Product: Xamarin.Mac
Classification: Desktop
Component: Library (Xamarin.Mac.dll) ()
Version: Master
Hardware: PC Mac OS
: --- normal
Target Milestone: ---
Assignee: Rolf Bjarne Kvinge [MSFT]
Depends on:
Reported: 2015-06-30 11:52 UTC by Chris Hamons
Modified: 2015-07-01 06:07 UTC (History)
1 user (show)

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

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 on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Chris Hamons 2015-06-30 11:52:56 UTC
From: https://kb.xamarin.com/agent/case/178944

Here's the test case:


Unzip this zip:


Into a folder in ~/Documents/TestFiles

And run the C# example. Press list files multiple times and note memory increase.

Here's an objective-c version that doesn't appear to leak:

Comment 1 Chris Hamons 2015-06-30 14:26:12 UTC
Here's a log of the programming running/leaking with debugging turned on.

Comment 3 Rolf Bjarne Kvinge [MSFT] 2015-07-01 06:07:07 UTC
What happens is that enumerating files puts objects into the current NSAutoreleasePool, which is drained when the frame that created the current NSAutoreleasePool completes execution. Xamarin.Mac automatically creates an NSAutorelease pool for every thread, which is drained when that thread exits. The problem is that the test case is using Task.Run, which uses the thread pool, which re-uses existing threads (and so the NSAutoreleasePool for that thread is not drained).

The fix is simple: just add an NSAutoreleasePool to the code:

	private Task<long> CounterTask()
		using (var pool = new NSAutoreleasePool ()) {
			 /* existing enumeration code */

and memory usage will go down when the CounterTask method completes.