You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cordova.apache.org by "Anthony May (JIRA)" <ji...@apache.org> on 2015/02/27 04:27:06 UTC

[jira] [Comment Edited] (CB-8332) Memory leak in loading files from disk with file plugin

    [ https://issues.apache.org/jira/browse/CB-8332?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14339674#comment-14339674 ] 

Anthony May edited comment on CB-8332 at 2/27/15 3:26 AM:
----------------------------------------------------------

After some profiling, I've found this to be related to the ARC memory management and the retain on FileHandle and the NSData. Done a quick rewrite from this: https://github.com/apache/cordova-plugin-file/blob/7ea51bc8b43550c88c4395a2734d47380df82aa3/src/ios/CDVLocalFilesystem.m#L661-L683

to

```
'- (void)readFileAtURL:(CDVFilesystemURL *)localURL start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback
{
    @autoreleasepool {
        NSString *path = [self filesystemPathForURL:localURL];
        NSString* mimeType = [CDVLocalFilesystem getMimeTypeFromPath:path];
        if (mimeType == nil) {
            mimeType = @"*/*";
        }
        
        CFURLRef url = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:path]);
        CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
        NSMutableData* readData = [[NSMutableData alloc] init];
        
        if(CFReadStreamOpen(stream))
        {
            uint8_t buf[1024];
            unsigned int len = 1024;
            while (CFReadStreamHasBytesAvailable(stream))
            {
                CFIndex numBytesRead = CFReadStreamRead(stream, buf, len);
                [readData appendBytes:&buf length:numBytesRead];
            }
        }
        
        callback(readData, mimeType, readData != nil ? NO_ERROR : NOT_FOUND_ERR);
        readData = nil;
}
```

This implementation still accumulates references in memory, but once it receives the first warning, the GC kicks and creates a stable memory profile.

Let me know if this works, and I'll update this to support the full functionality.


was (Author: amay0048):
After some profiling, I've found this to be related to the ARC memory management and the retain on FileHandle and the NSData. Done a quick rewrite from this: https://github.com/apache/cordova-plugin-file/blob/7ea51bc8b43550c88c4395a2734d47380df82aa3/src/ios/CDVLocalFilesystem.m#L661-L683

to

```
- (void)readFileAtURL:(CDVFilesystemURL *)localURL start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback
{
    @autoreleasepool {
        NSString *path = [self filesystemPathForURL:localURL];
        NSString* mimeType = [CDVLocalFilesystem getMimeTypeFromPath:path];
        if (mimeType == nil) {
            mimeType = @"*/*";
        }
        
        CFURLRef url = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:path]);
        CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
        NSMutableData* readData = [[NSMutableData alloc] init];
        
        if(CFReadStreamOpen(stream))
        {
            uint8_t buf[1024];
            unsigned int len = 1024;
            while (CFReadStreamHasBytesAvailable(stream))
            {
                CFIndex numBytesRead = CFReadStreamRead(stream, buf, len);
                [readData appendBytes:&buf length:numBytesRead];
            }
        }
        
        callback(readData, mimeType, readData != nil ? NO_ERROR : NOT_FOUND_ERR);
        readData = nil;
}
```

This implementation still accumulates references in memory, but once it receives the first warning, the GC kicks and creates a stable memory profile.

Let me know if this works, and I'll update this to support the full functionality.

> Memory leak in loading files from disk with file plugin
> -------------------------------------------------------
>
>                 Key: CB-8332
>                 URL: https://issues.apache.org/jira/browse/CB-8332
>             Project: Apache Cordova
>          Issue Type: Bug
>          Components: Plugin File
>    Affects Versions: 3.5.0
>         Environment: iOS
>            Reporter: Patrick Richards
>            Assignee: Shazron Abdullah
>
> When loading files from disk, the file plugin appears to leak memory. Using instruments it can be narrowed down to -[CDVFilesystemURLProtocol startLoading], which is in CDVFile.m on line 150.
> (https://github.com/apache/cordova-plugin-file/blob/967ca4d848d6bea0bad5a0d334b8d9f1ea2c4680/src/ios/CDVFile.m#L150)
> To reproduce:
> • have the iOS app download a file using plugin-file-transfer
> • store that file to persistent storage
> • load that file from disk and the app will leak
> We have a very simple proof of concept that downloads a large photo, then constantly refreshes an iFrame which triggers loading the photo from persistent storage. The memory usage of the app climbs over time (with various dips at memory warnings), then crashes due to memory pressure. We can upload this sample project/provide a link if needed – there doesn’t appear to be a way to attach files.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@cordova.apache.org
For additional commands, e-mail: issues-help@cordova.apache.org