[swift-corelibs-dev] NSMutableData memory leak
Philippe Hausler
phausler at apple.com
Mon May 16 11:43:28 CDT 2016
I think there is probably some likely issue with the fact that NSMutableData is a subclass and the layout initialization is not properly setup during the init for that object.
__kCFDontDeallocate is used to mark the allocated memory as managed by the deallocator blocks. So I bet the problem is that the code-path for NSMutableData(capacity: 0) is hitting the don’t deallocate code path incorrectly (where as the other versions are hitting the appropriate flagging; hence the crashes)
Does this also occur in the Darwin builds of this? (Using SwiftFoundtion instead of Foundation)
> On May 16, 2016, at 9:34 AM, Ian Partridge via swift-corelibs-dev <swift-corelibs-dev at swift.org> wrote:
>
> import Foundation
>
> while true {
> var myData: NSMutableData? = NSMutableData(capacity: 0)
> myData = nil
> }
>
> Running this infinite loop with swift-corelibs-foundation shows a steady memory leak, with the process's RSS increasing over time. No leak is seen with Foundation on Darwin.
>
> Instrumenting with Valgrind's massif profiler shows this stacktrace is responsible for the leak:
>
> 67.36% (114,349B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
> ->65.01% (110,352B) 0x59F7A89: _CFDataInit
> ->65.01% (110,352B) 0x5B8A8DF: _TTSf4n_n_n_g_n___TFC10Foundation6NSDatacfT5bytesGSqGSpT___6lengthSi4copySb11deallocatorGSqFTGSpT__Si_T___S0_
> ->65.01% (110,352B) 0x5B873ED: _TFC10Foundation13NSMutableDataCfT8capacitySi_GSqS0__
> ->65.01% (110,352B) 0x40105D: main
> I've stepped through the code with a debugger and observed that the requested capacity is thrown away <https://github.com/apple/swift-corelibs-foundation/blob/df239bbbdf5bcdd9ea31c394c6af4dd7c328f99d/Foundation/NSData.swift#L904> [1] to begin with. The leak occurs regardless of the capacity requested.
>
> The deinitializer for NSData does call through to _CFDeinit(), which does then call the finalize() <https://github.com/apple/swift-corelibs-foundation/blob/ea6179dd35be2c7d9a8f953579f626a5f1be6511/CoreFoundation/Base.subproj/CFRuntime.c#L1773> [2] function and hence through to __CFDataDeallocate() <https://github.com/apple/swift-corelibs-foundation/blob/ea3014bd7883e428727272118cbf37dc56522be6/CoreFoundation/Collections.subproj/CFData.c#L294> [3]. However, once in __CFDataDeallocate(), the code to free the buffer is skipped, because __kCFDontDeallocate is set.
>
> If I hack _CFDataInit() so that __kCFDontDeallocate isn't set (by commenting out this line <https://github.com/apple/swift-corelibs-foundation/blob/ea3014bd7883e428727272118cbf37dc56522be6/CoreFoundation/Collections.subproj/CFData.c#L337> [4]) then I get crashes elsewhere - so this obviously isn't the right approach.
>
> I can see that some work has been done in this area <https://github.com/apple/swift-corelibs-foundation/commit/ea3014bd7883e428727272118cbf37dc56522be6> [5] previously by Philippe so I'm wondering if anyone can advise on what might be going on here?
>
> The init?(length:) initializer avoids CFData entirely and calls malloc() and free() directly. I'm not sure why that approach was taken and whether it's relevant to my issue.
>
> Any help would be gratefully received!
>
> Thanks,
>
> [1] https://github.com/apple/swift-corelibs-foundation/blob/df239bbbdf5bcdd9ea31c394c6af4dd7c328f99d/Foundation/NSData.swift#L904 <https://github.com/apple/swift-corelibs-foundation/blob/df239bbbdf5bcdd9ea31c394c6af4dd7c328f99d/Foundation/NSData.swift#L904>
> [2] https://github.com/apple/swift-corelibs-foundation/blob/ea6179dd35be2c7d9a8f953579f626a5f1be6511/CoreFoundation/Base.subproj/CFRuntime.c#L1773 <https://github.com/apple/swift-corelibs-foundation/blob/ea6179dd35be2c7d9a8f953579f626a5f1be6511/CoreFoundation/Base.subproj/CFRuntime.c#L1773>
> [3] https://github.com/apple/swift-corelibs-foundation/blob/ea3014bd7883e428727272118cbf37dc56522be6/CoreFoundation/Collections.subproj/CFData.c#L294 <https://github.com/apple/swift-corelibs-foundation/blob/ea3014bd7883e428727272118cbf37dc56522be6/CoreFoundation/Collections.subproj/CFData.c#L294>
> [4] https://github.com/apple/swift-corelibs-foundation/blob/ea3014bd7883e428727272118cbf37dc56522be6/CoreFoundation/Collections.subproj/CFData.c#L337 <https://github.com/apple/swift-corelibs-foundation/blob/ea3014bd7883e428727272118cbf37dc56522be6/CoreFoundation/Collections.subproj/CFData.c#L337>
> [5] https://github.com/apple/swift-corelibs-foundation/commit/ea3014bd7883e428727272118cbf37dc56522be6 <https://github.com/apple/swift-corelibs-foundation/commit/ea3014bd7883e428727272118cbf37dc56522be6>
>
> --
> Ian Partridge
>
> _______________________________________________
> swift-corelibs-dev mailing list
> swift-corelibs-dev at swift.org
> https://lists.swift.org/mailman/listinfo/swift-corelibs-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-corelibs-dev/attachments/20160516/58049ac4/attachment.html>
More information about the swift-corelibs-dev
mailing list