Skip to content
This repository has been archived by the owner on Aug 11, 2020. It is now read-only.

Memory leak on iOS 10 devices #312

Closed
jlowe234 opened this issue Aug 25, 2016 · 57 comments
Closed

Memory leak on iOS 10 devices #312

jlowe234 opened this issue Aug 25, 2016 · 57 comments

Comments

@jlowe234
Copy link
Contributor

jlowe234 commented Aug 25, 2016

There appears to be a memory leak occurring when using the scanner against iOS 10 devices.

I've created the following test case that allocates/deallocates successfully on an iPad with iOS 7.1.2, but will never dealloc the scanner on iOS 10.

Here's the app that I used in my test. Just a standard Cordova (5.3.3) + barcodescanner (6.0.1) with the following index.html.

<!DOCTYPE html>
<!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 -->
<html>
    <head>
        <!--
         Customize this policy to fit your own app's needs. For more guidance, see:
         https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy
         Some notes:
         * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication
         * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
         * Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
         * Enable inline JS: add 'unsafe-inline' to default-src
         -->
        <!--<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' data: gap: https://ssl.gstatic.com ; style-src 'self'; media-src *">-->
            <meta name="format-detection" content="telephone=no">
                <meta name="msapplication-tap-highlight" content="no">
                    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
                        <link rel="stylesheet" type="text/css" href="css/index.css">
                            <title>Hello World</title>
                            </head>
    <body>
        <div class="app">
            <script type="text/javascript" src="cordova.js"></script>
            <script type="text/javascript" src="js/index.js"></script>
            <script type="text/javascript">
                function scanTest(field) {
                    try {
                        var scanner = window.cordova.require("phonegap-plugin-barcodescanner.BarcodeScanner");
                        scanner.scan(
                                     function (result) {
                                     if (document.getElementById(field)) {
                                     debugger;

                                     document.getElementById(field).innerHTML = result.text;

                                     } else {
                                     alert("field is bad");
                                     }
                                     });
                    } catch (e) {
                        alert("ErrorDescription: " + e);
                    }
                }

            </script>
            <h1>Apache Cordova</h1>
            <div id="deviceready" class="blink">
                <p class="event listening">Connecting to Device</p>
                <p class="event received">Device is Ready</p>
                <p id="scan">Test scan</p>
                <a href="#" onclick='scanTest("scan");' id="scanshortcut">Scan</a>
            </div>
        </div>

    </body>
</html>
@jlowe234
Copy link
Contributor Author

I'm not entirely certain how to resolve something like this. Here is some of the information that I've found so far. I upgraded cordova to the most recent version and attempted to rebuild this app and encountered the same problem.

You can see based on the memory report between ios 10 and 7(and 9) that something is really not right. The first memory report is from the iOS 10 device I'm testing with. The second is iOS 7. Each time the scanner loads, it increases the footprint of the application drastically, as well as taking up somewhere in the ballpark of 100-150 MB in the "Other Processes" area.
ios10
ios7-ipad

I'm not entirely sure what I'm looking for, but I've run the application in the instrument panel looking for leaks, and I don't really see anything nearly as large as the memory report is encountering. Each scan seems to leak a negligible amount ( < 1 KB) on the instrument panel, so I'm not really sure how to trace this.

Is there anyone who would be able to assist me? My obj c knowledge base is lacking.

@jlowe234
Copy link
Contributor Author

I've noticed that there appears to be a rather large IOKit allocation in the VM that i'm not sure where it's coming from. You can see here from the VM Summary that with the iPad it is not allocating these 100 MiB chunks, but does so in iOS 10. I'm still not really that sure where this is coming from or what would force these extra calls. It's every time the scanner is executed that one of these 26364 page, 102.88 MiB allocations occurs. This is only happening on the iOS 10 device, and does not appear to be occurring at all on the iPad.

ios10 iokit
ipad iokit

@mohlemeyer
Copy link

(Probably) the same issue here: I have an Ionic app with this plugin which works flawlessly on iOS 9. The same app on iOS 10 crashes on the 5th or 6th scan. When running the app from Xcode on the device, the error message in the output window is:

Message from the debugger: Terminated due to memory issue.

Looking at the memory consumption, the app starts out with about 35 - 50 MB and on each scan between 20 and 30 MB are added and never freed. When memory usage exceeds 150 MB the next scan reliably crashes the app.

I'm not sure how to proceed. Since the bug is only present with iOS 10 beta and not in iOS 9 it might have to be resolved by Apple, not the barcode scanner plugin?

@jlowe234
Copy link
Contributor Author

jlowe234 commented Sep 1, 2016

I don't even get the message from the debugger with my testing. It just crashes the connection and shows nothing.

I have however found that the leak of 100 MiB per scan is tied to this line in the -setUpCaptureSession method:
NSDictionary* videoOutputSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey ];

I removed that from the plugin and it appears to leak a good amount less than before. The only issue that I am having difficulty with right now is understanding why this is a leak now in iOS 10, and where the 10-15 MiB leak is in the application itself.

Removing that line has made it so that it takes about 20-30 scans before I can crash the application. It will only seem to crash after the application leak manages to get to critical mass (highest I've gotten so far in testing is 515 MB).

I believe it has something to do with the capture stream from the AVCaptureSession/AVCaptureVideoDataOutput but I just don't understand enough about what I'm looking at/into to really find the correct course.

The majority of the leaked memory seems to be dirty IOKit VM allocations that just float there forever.

@lesion
Copy link

lesion commented Sep 2, 2016

It's the same here with an iOS 9.3.5:
after ~30 scan the app crash.
Temporary solved using Telerik-Verified-Plugins/BarcodeScanner as with this plugin is working (tested with more than 100 scan)

hope this helps..

@lesion
Copy link

lesion commented Sep 2, 2016

ok, don't know why, but removing the animation breaks everything again (always after ~30 scan) -> 3d8e3922d8ee79cc5a030c36ee59efb1ea1ac234

I think could be something here (check the differences):

phonegap/src/ios/CDVBarcodeScanner.mm

- (void)barcodeScanDone:(void (^)(void))callbackBlock {
    self.capturing = NO;
    [self.captureSession stopRunning];
    [self.parentViewController dismissViewControllerAnimated:YES completion:callbackBlock];

telerik/src/ios/CDVBarcodeScanner.mm

- (void)barcodeScanDone {
    self.capturing = NO;
    [self.captureSession stopRunning];
    [self.parentViewController dismissViewControllerAnimated: YES completion:nil];

and telerik:

- (void)barcodeScanSucceeded:(NSString*)text format:(NSString*)format {
    dispatch_sync(dispatch_get_main_queue(), ^{
        [self barcodeScanDone];
        AudioServicesPlaySystemSound(_soundFileObject);
        [self.plugin returnSuccess:text format:format cancelled:FALSE flipped:FALSE callback:self.callback];
    });
}

phonegap:

- (void)barcodeScanSucceeded:(NSString*)text format:(NSString*)format {
    dispatch_sync(dispatch_get_main_queue(), ^{
        [self barcodeScanDone:^{
            [self.plugin returnSuccess:text format:format cancelled:FALSE flipped:FALSE callback:self.callback];
        }];
        AudioServicesPlaySystemSound(_soundFileObject);
    });
}

@jlowe234
Copy link
Contributor Author

jlowe234 commented Sep 2, 2016

I saw no change with what you mentioned here. The difference between the Phonegap and Telerik versions of the scanner is how they perform the barcodeScanDone event. That was the only change I saw between the two. Regardless of that, I was still able to encounter the small memory leak with the scanner.

There still appears to be something around a 10 MB allocation that I cannot find and cannot seem to release from some aspect of the AVCaptureSession. The allocation occurs when the AVCaptureSession is started, but doesn't dealloc after stopping the session. It appears to be another smaller IOKit allocation.

@Mole93
Copy link

Mole93 commented Sep 7, 2016

I don't think so that the callback on barcodeScanSucceded is the problem. I think could be a issue of iOS 10 that doesn't release the memory because in iOS 9 it's working fine. We can see at the fallowing link https://forums.developer.apple.com/thread/61620 that other developers have a problem with the AVCaptureSession that it is a class that the library uses.

I have another issue with the iphone 4s but with iOS 9.3.5. The issue is the same after a few times the app crash . Has someone had the same problem?

@jlowe234
Copy link
Contributor Author

jlowe234 commented Sep 7, 2016

That forum post is my post regarding this issue. As for the issue appearing on other platforms, I have an ancient iPad (i think first gen) and an iPhone 5c that were running the scanner without issues. It sounds similar to what I'm encountering on iOS 10, although I'm not specifically encountering the issue.

The biggest problem so far that I've found is tied to the video output settings. That is what is causing the 100 MiB allocations for IOKit. I was able to verify that by changing to another setting (420YpCbCr8BiPlanarVideoRange and 420YpCbCr8BiPlanarFullRange) for testing sake and seeing that the memory is not being allocated in the same manner. Obviously the scanner doesn't work correctly with different settings, but there still remains a small increase in the application footprint.

I'm still investigating this, but time is running out on my end and I'm running out of resources.

@Mole93
Copy link

Mole93 commented Sep 9, 2016

Hello guys,

I investigated for this issue and i found the problem on the c++ class.
A lot of objects are still in the memory also when barcode viewcontroller is closed (to see the picture below).
screen shot 2016-09-09 at 15 01 07

So we must delete those files because every time that we open the barcode viewcontroller it takes from 20 to 30 mb so it's a big problem.

I tried to investigate on the C++ code but i don't understand everything so i need of help.

@mohlemeyer
Copy link

The problem persists with iOS 10 final and plugin version 6.0.2.
With an iPhone 6s Plus the app dies on the third scan.

@Mole93
Copy link

Mole93 commented Sep 12, 2016

Guys i created a new plugin and i fixed this issue.
To use it you need to delete the native classes and to add my classes and you can see the difference.

Mole93/plugin-barcode-ios

@startupfoundry
Copy link

@Mole93 could you submit a PR to the main project to fix the memory leak? Thanks for your work!

@Mole93
Copy link

Mole93 commented Sep 13, 2016

@startupfoundry I can't because i changed completely the core logic of this plugin.
I deleted all classes (native) of this plugin and i copied the interface with javascript after i integrated this barcode library (MTBBarcodeScanner) as core of my plugin.
So i think that i can't create a PR with my fixed but i ask you to try my plugin and you can see the difference. It's faster and it uses only 3/4 mb for the process. It is a very good solution for the performance because the problem with the official plugin is the C++ classes because they create a lot of memory leak. I analyse the code and i saw that there are a lot of objects which are deleted but they forget to delete the sub object so the still in the memory.

@jlowe234
Copy link
Contributor Author

Based on what I can see from @Mole93's branch and the plugin he cloned, it looks like I might have a working code base to resolve this issue.

I'm not entirely sure if it won't provide other issues, because the core of his alternate scanner logic uses an AVCaptureMetadataOutputObjectsDelegate and the underlying metadataOutput structure to replace the AVCaptureVideoDataOutputSampleBufferDelegate and the zxing library to identify the barcodes.

If my testing confirms this, I will submit a PR with the alternate methods.

@startupfoundry
Copy link

@jlowe234 awesome. Thanks for your work on this guys!

jlowe234 added a commit to jlowe234/phonegap-plugin-barcodescanner that referenced this issue Sep 15, 2016
Changed delegate to AVCaptureMetadataOutputObjectsDelegate to support AVFoundation's barcode scanner reader without memory leaks from the zxing library & the SampleBuffer delegate.
jlowe234 added a commit to jlowe234/phonegap-plugin-barcodescanner that referenced this issue Sep 16, 2016
Changed CDVbcsProcessor to use AVCaptureMetadataOutputDelegate instead of SampleBuffer and zxing to resolve iOS 10 memory leak issue.
mikedemarais added a commit to mikedemarais/phonegap-plugin-barcodescanner that referenced this issue Sep 19, 2016
@juliancesar
Copy link

Hey guys, have a release date the 6.0.3 with this fix? I have the same issue here!

SunLn added a commit to SunLn/phonegap-plugin-barcodescanner that referenced this issue Sep 20, 2016
@startupfoundry
Copy link

@jlowe234 are you comfortable using your version in a production environment?

@jlowe234
Copy link
Contributor Author

I do feel comfortable with it. I'm awaiting sign off on an update with one of my apps that contains the submitted changes. My testing has been great so far.

I believe the only possible issue area is with UPC-A and EAN13 formatting because that has been slightly modified to fit with the new metadata structure. Admittedly, the majority of my app's barcode capabilities are related to QR.

@azn1viet
Copy link

azn1viet commented Sep 20, 2016

I still have the same issue with the latest version of this plugin. It happens to the iPhone 6, iOS 10 after the 4th scans. App crashed. I guess I have version 6.0.2 which is not included this fix, right?

@osirisr
Copy link

osirisr commented Sep 20, 2016

I have the same issue. Works perfectly on iOS 9, but crashes on iOS 10 after opening 3-4 times.

iPhone 5S
Version 10.0.1
Barcode Scanner version 6.0.1

@john-doherty
Copy link

john-doherty commented Sep 20, 2016

I was having the same issue so I initially switched to @Mole93's plugin and it solved the crashing problem but it was very slow in comparison.

I then manually copied the RAW contents of the CDVBarcodeScanner.mm file from @jlowe234's pending pull request and replace the contents of ./plugins/phonegap-plugin-barcodescanner/src/ios/CDVBarcodeScanner.mm in my project and executed the following command cordova platform remove ios && cordova platform add ios && cordova build ios

It's now working fine. No crashes, no memory leaks. Thanks @jlowe234 & @Mole93!

EDIT: Just to add, I can confirm this pull request resolves the memory leak.

@nOzwald
Copy link

nOzwald commented Sep 23, 2016

Any plans to include @jlowe234's pull request any time soon?

@startupfoundry
Copy link

Honestly this needs to be merged ASAP. This bug causes crashes for every iOS 10 user (Over 30%+ of iPhones have already updated to 10).

@lesion
Copy link

lesion commented Sep 23, 2016

Not so clean but you can reference a github branch as a plugin, so here's a "do not try this at home" way:

inside your cordova.xml

<plugin name="phonegap-plugin-barcodescanner" spec="https://github.com/jlowe234/phonegap-plugin-barcodescanner.git#leak#312" />

quick & dirty

@fabiocaccamo
Copy link

fabiocaccamo commented Oct 3, 2016

@lesion thanks, you saved me :)
I had this problem on an iPhone 6 with iOS 9.

@jlowe234
Copy link
Contributor Author

I took the project that I had from the first post and updated the plugin with the source from my repo. My barcode scans were as follows for the above two codes:

Barcode 1 -
Format: CODE_128, Text: 420202609405518922818001123454

Barcode 2 -
Format: CODE_128, Text: 420100109261290100106971583637

Both codes appear to be correct based on what I could look up on the USPS tracking number format. The prefix is 420 + 5 digits (destination ZIP) plus the displayed numbers under the code.

I really can't tell you what could be wrong without seeing a project that can reliably reproduce the issue. Do you have a small project that you can share which will demonstrate your reported issue?

@caixiang2014
Copy link

I use https://github.com/jlowe234/phonegap-plugin-barcodescanner plugin to scan barcode, but I can't scan follow barcode:
201304191139442489
I need to help.
thanks

@jlowe234
Copy link
Contributor Author

What kind of barcode is that? Does it scan with the existing plugin?

I could not get that barcode to scan with my branch of the plugin nor the current version of the plugin.

@cepm-nate
Copy link
Contributor

jlowe234, Thank you so much!
I can confirm that using your branch fixes the "crashes after X scans" and adds Code93 recognition.
It also added a bonus feature I was going to look into coding: How to scan ONLY where the red line crosses the image!
You do great work, and I hope that this (and your other) pull requests are merged in soon!

@inzi
Copy link

inzi commented Oct 13, 2016

Same - I'm anxious for pull request #338 to be merged. There are only a few companies out there who all want $1000s a year for PDF417. When merged, I'm going to find a way send you a $ tip, jlowe234.

@wilsoncmartins
Copy link

@caixiang2014 this code looks be Codabar type.

@jlowe234
Copy link
Contributor Author

If that is codabar, it is not supported with the ios version of the plug-in. That would be something that you would need to open a separate issue regarding. There are a few other Barcode variants that can be added via the AVMetadata change in my PR but I am unfamiliar with them so I did not add them.

@EddyVerbruggen
Copy link
Collaborator

Hi folks,

Thanks a lot for figuring this out and of course a HUGE THANKS to @jlowe234 for his PR which I've just merged and released as part of 6.0.3 🎉

@osirisr
Copy link

osirisr commented Oct 23, 2016

The barcode scanner is still crashing for iOS 10 after 4-5 trials of opening/closing the camera. Is anyone else having this issue still? If not, I am testing in Ionic View and haven't tested and compiled to a native app yet, so this may be the issue - but I doubt it.

iPhone 5S
Version 10.0.1
Barcode Scanner version 6.0.3

@dmgfjaved
Copy link

I tested on iPhone 6 with IOS 10.0.2 and I don't see any crashing. I tested after compiling to a native app.

@EddyVerbruggen
Copy link
Collaborator

@osirisr Ionic View is not running the latest barcodescanner plugin version. By its very nature it's lagging behind.

@osirisr
Copy link

osirisr commented Oct 25, 2016

@EddyVerbruggen Well I use the command cordova plugin add phonegap-plugin-barcodescanner and then when I check for the installed version using cordova plugin list I get this: phonegap-plugin-barcodescanner 6.0.3 "BarcodeScanner"

It is returning version 6.0.3, which I assume is the same as the version 6.0.3 that's here on Github... Right?

@dmgfjaved - I have iOS 10.0.1 ... it could be that this fix only works for iOS 10.0.2+

I'll provide an update once I compile to native app.

@EddyVerbruggen
Copy link
Collaborator

@osirisr You said "I am testing in Ionic View" which according to the Apple AppStore has a latest version of September 1st so your runtime doesn't include version 6.0.3 of the barcode scanner plugin. Also, check the list of plugin versions supported by Ionic View here.

@ghost
Copy link

ghost commented Oct 25, 2016

I think the fix is actuallybpart of release 6.0.3.

On Sunday, 23 October 2016, osirisr notifications@github.com wrote:

The barcode scanner is still crashing for iOS 10 after 4-5 trials of
opening/closing the camera. Is anyone else having this issue still? If not,
I am testing in Ionic View and haven't tested and compiled to a native app
yet, so this may be the issue - but I doubt it.

iPhone 5S
Version 10.0.1
Barcode Scanner version 6.0.1


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#312 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AJNaXP-3ngeSGWx89TitktxvivveixJ-ks5q2vfXgaJpZM4JtiVZ
.

@osirisr
Copy link

osirisr commented Oct 26, 2016

@EddyVerbruggen I was unaware that Ionic View does not use the cordova plugin version you have installed in the project. After compiling and running on iOS 10.0.1 iPhone 5S, the barcode camera is no longer crashing! Thank you!

@jaguarg
Copy link

jaguarg commented Dec 3, 2016

Issue is still there with 6.0.3 for me. is there a workaround, even temporarily I need to get an update of my app pretty quickly.

Many thanks

@Mole93
Copy link

Mole93 commented Dec 3, 2016

you can use my plugin plugin-barcode-ios to fix this issue very quickly

@jaguarg
Copy link

jaguarg commented Dec 3, 2016

Thx @Mole93 , that is brilliant I am now using your plugin.

It seems that I lost the red line on the capture window . I only got the green square.
Is there an option to enable the red guide line ?

@Mole93
Copy link

Mole93 commented Dec 3, 2016

@jaguarg which red line? Do you have any img that you can show me?

@jaguarg
Copy link

jaguarg commented Dec 3, 2016

That's what I use to have ... now I only get the green box ...

screen shot 2016-12-03 at 22 18 51

@Mole93
Copy link

Mole93 commented Dec 3, 2016

@jaguarg ok, I got it. Can you open the issue on my plugin, please? I'll fix it soon

@jaguarg
Copy link

jaguarg commented Dec 3, 2016

done.
Thank you so much for your help .

@arruix
Copy link

arruix commented Feb 22, 2017

Any update on this issue? I'm still having this issue on iOS 10.1+

@lock
Copy link

lock bot commented Jun 8, 2018

This thread has been automatically locked.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 8, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests