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:
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.
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@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 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.
Yes, I have been investigating this using a new TestNSData test under XCode.
···
On 16 May 2016 at 17:43, Philippe Hausler <phausler@apple.com> wrote:
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)