Bug 27274 - Byte array read from file leaks under specific conditions
Summary: Byte array read from file leaks under specific conditions
Status: RESOLVED ANSWERED
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: XI 8.6.0
Hardware: PC Mac OS
: Normal normal
Target Milestone: Untriaged
Assignee: Rodrigo Kumpera
URL:
Depends on:
Blocks:
 
Reported: 2015-02-20 17:52 UTC by Randall Schmidt
Modified: 2015-03-25 13:46 UTC (History)
3 users (show)

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


Attachments
Reproduction case (59 bytes, text/plain)
2015-02-20 17:55 UTC, Randall Schmidt
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 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:
Status:
RESOLVED ANSWERED

Description Randall Schmidt 2015-02-20 17:52:29 UTC
Profile the attached solution with heap shot. A file is read into unused byte arrays 5 times. Two of those byte arrays are shown by heap shot to still be in memory even after the forced garbage collection (Heap Shot shows 80+ MB of Byte[] in memory).

Curiously, the null check early return in the constructor of Class1 is necessary for this leak to occur. Without it, Heap Shot shows no evidence of a leak.

I was wondering if maybe this is just a symptom of caching, however, it appears the file is in memory twice. If it were being cached, I would only expect it once.
Comment 1 Randall Schmidt 2015-02-20 17:55:50 UTC
Created attachment 9956 [details]
Reproduction case
Comment 2 Sebastien Pouliot 2015-02-21 11:40:18 UTC
Was your original project different?  The attached project was not set for heapshot when I tried it (maybe it's a bit diffferent)

Once I enabled it Heapshot reports a `Total memory` of 42MB when I try this on a (32bits) device.

Can you tell us:

* which type of device you used ?

* which exact version of Xamarin.iOS (and other software) was used ? (from XS about dialog)
Comment 3 Randall Schmidt 2015-02-23 11:17:03 UTC
Sebastien,

I zipped the same solution I saw the behavior with, but maybe I zipped it before I enabled the right settings for device builds.

There seems to be some randomness. Running this a few more times this morning I have seen ~0, ~40 and ~80 MB on an iPad 3. I would expect to always see 0.

I'm using an iPad 3, Xamarin.iOS 8.6.20, XCode 6.1.1, and mono 3.12.0 on OS X 10.9.5
Comment 4 Randall Schmidt 2015-02-23 11:33:19 UTC
Sorry, that's Xamarin.iOS 8.6.1.20
Comment 5 Sebastien Pouliot 2015-02-24 18:38:33 UTC
@Randall thanks for the extra information.

@Rodrigo any clue why one (or more) of those buffer never gets collected ? (it's not been random to me, always a single instance keeps being reported).
Comment 6 Rodrigo Kumpera 2015-02-24 18:41:38 UTC
Yes, conservative stack scanning explains this.
Comment 7 Randall Schmidt 2015-03-24 17:28:46 UTC
So...
Comment 8 Rodrigo Kumpera 2015-03-25 02:20:37 UTC
So it explains what you've been experiencing. It's the expected behavior of GC with conservative stack scanning.
Comment 9 Randall Schmidt 2015-03-25 09:59:00 UTC
I got that, but the expected behavior isn't very desirable at all. How do we prevent the byte array from leaking?
Comment 10 Rodrigo Kumpera 2015-03-25 13:46:18 UTC
It will eventually  be collected when the related stack frame is replaced with other values.

The fix is to observe memory consumption over time and not over a single operation to find meaningful issues.

We have in our roadmap to address this issue in the future.