Bug 59105 - Memory leak when creating large array.
Summary: Memory leak when creating large array.
Status: CONFIRMED
Alias: None
Product: iOS
Classification: Xamarin
Component: Mono runtime / AOT compiler (show other bugs)
Version: XI 10.12 (d15-3)
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Zoltan Varga
URL:
Depends on:
Blocks:
 
Reported: 2017-08-29 23:33 UTC by Jon Goldberger [MSFT]
Modified: 2017-08-31 18:55 UTC (History)
3 users (show)

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


Attachments
Test Project (18.79 KB, application/zip)
2017-08-29 23:33 UTC, Jon Goldberger [MSFT]
Details


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 59105 on Developer Community or GitHub 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: Developer Community HTML or GitHub Markdown
  • 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:
Status:
CONFIRMED

Description Jon Goldberger [MSFT] 2017-08-29 23:33:00 UTC
Created attachment 24464 [details]
Test Project

## Description

On 32 bit iOS devices (or simulators of the same devices), there is a memory leak if you create a large array in a button event handler (using target/action pair from storyboard, not .NET event subscriptions) even if it is asigned to a local variable and that variable is set to null before the method returns. E.g. the following code will leak memory:

>void BtnRun_TouchUpInside(object sender, EventArgs e)
>{
>     try
>     {
>           byte[] emptyArray = new byte[1024 * 1024 * 200];//200mb
>           emptyArray = null;
>
>           GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
>           System.GC.Collect(2, GCCollectionMode.Forced, true, true);
>           Console.WriteLine($"Allocated: {GC.GetTotalMemory(true)}");
>     }
>     catch (Exception ex)
>     {
>           Console.WriteLine("Exception: " + ex.Message);
>     }
>}


## Notes

The DidReceiveMemoryWarning method override on the view controller is never fired. 

If instead of the following two GC lines of code:

>GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
>System.GC.Collect(2, GCCollectionMode.Forced, true, true);

I call GC.Collect(), it takes longer to get the out of memory exception but it still leaks. 

The test solution includes a UITest project. I ran this test in Test cloud on iOS devices from the 4s to the 7. The test only failed on the 4s and the 5, IOW the 32 bit devices. Link to test cloud run in private comment below. 


## Steps to reproduce

1. Open the attached solution

2. Deploy to an iPhone 5 (or 4s) simulator 

3. Tap the run button repeatedly and watch the console output.

Expected result: Memory usage should not go up very much and should not get OutOfMemory exception. 

Actual result: Memory usage increases by about 200 MB every button tap and app eventually hits an OutOfMemoryException. 


## Environment

=== Visual Studio Enterprise 2017 for Mac ===

Version 7.1 (build 1297)
Installation UUID: f86726f2-bd5d-4610-867e-44e82f306ca2
Runtime:
	Mono 5.2.0.215 (d15-3/da80840) (64-bit)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 502000215

=== NuGet ===

Version: 4.3.0.2418

=== .NET Core ===

Runtime: /usr/local/share/dotnet/dotnet
Runtime Versions:
	1.1.1
	1.0.4
	1.0.0
SDK: /usr/local/share/dotnet/sdk/1.0.1/Sdks
SDK Versions:
	1.0.1
	1.0.0-preview2-003121
MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/5.2.0/lib/mono/msbuild/15.0/bin/Sdks

=== Xamarin.Profiler ===

Version: 1.5.5
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Apple Developer Tools ===

Xcode 8.3.3 (12175.1)
Build 8E3004b

=== Xamarin.Mac ===

Version: 3.6.0.19 (Visual Studio Enterprise)

=== Xamarin.Android ===

Version: 7.4.0.21 (Visual Studio Enterprise)
Android SDK: /Users/jongoldberger/Library/Developer/Xamarin/android-sdk-macosx
	Supported Android versions:
		4.0.3 (API level 15)
		4.1   (API level 16)
		4.2   (API level 17)
		4.3   (API level 18)
		4.4   (API level 19)
		5.0   (API level 21)
		5.1   (API level 22)
		6.0   (API level 23)
		7.0   (API level 24)
		7.1   (API level 25)

SDK Tools Version: 26.0.2
SDK Platform Tools Version: 25.0.5
SDK Build Tools Version: 26.0.1

Java SDK: /usr
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)

Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

=== Xamarin.iOS ===

Version: 10.12.0.20 (Visual Studio Enterprise)
Hash: 80b8487d
Branch: d15-3
Build date: 2017-08-18 16:07:26-0400

=== Build Information ===

Release ID: 701001297
Git revision: 9c5299666538b2f8baf501418a5c064d784d64da
Build date: 2017-08-07 11:29:35-04
Xamarin addins: 3bb0c32a14f1b7e368bf5ac53a84c3581c019391
Build lane: monodevelop-lion-d15-3

=== Operating System ===

Mac OS X 10.12.6
Darwin 16.7.0 Darwin Kernel Version 16.7.0
    Thu Jun 15 17:36:27 PDT 2017
    root:xnu-3789.70.16~2/RELEASE_X86_64 x86_64
Comment 4 Sebastien Pouliot 2017-08-31 18:55:41 UTC
It sounds like the GC cannot reclaim it, which could happen because of the conservative stack scanning. In this case it's not exactly a leak, but _hopefully_ just a delay.

-> runtime for confirmation