<div dir="ltr"><pre style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:11.9px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;overflow:auto;border-radius:3px;word-wrap:normal;color:rgb(51,51,51);background-color:rgb(247,247,247)"><span class="" style="color:rgb(167,29,93)">import</span> <span class="" style="color:rgb(0,134,179)">Foundation</span>
<span class="" style="color:rgb(167,29,93)">while</span> <span class="" style="color:rgb(0,134,179)">true</span> {
<span class="" style="color:rgb(167,29,93)">var</span> myData: NSMutableData? <span class="" style="color:rgb(167,29,93)">=</span> NSMutableData(capacity: <span class="" style="color:rgb(0,134,179)">0</span>)
myData <span class="" style="color:rgb(167,29,93)">=</span> <span class="" style="color:rgb(0,134,179)">nil</span>
}</pre><div><br></div><div>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.</div><div><br></div><div>Instrumenting with Valgrind's massif profiler shows this stacktrace is responsible for the leak:</div><div><br></div><div><pre style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:11.9px;margin-top:0px;margin-bottom:16px;font-stretch:normal;line-height:1.45;padding:16px;overflow:auto;border-radius:3px;word-wrap:normal;color:rgb(51,51,51);background-color:rgb(247,247,247)"><code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:11.9px;padding:0px;margin:0px;border-radius:3px;border:0px;display:inline;max-width:initial;overflow:initial;line-height:inherit;word-wrap:normal;background:transparent">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</code></pre></div><div>I've stepped through the code with a debugger and observed that the requested capacity is <a href="https://github.com/apple/swift-corelibs-foundation/blob/df239bbbdf5bcdd9ea31c394c6af4dd7c328f99d/Foundation/NSData.swift#L904">thrown away</a> [1] to begin with. The leak occurs regardless of the capacity requested.</div><div><br></div><div>The deinitializer for NSData does call through to _CFDeinit(), which does then call the <a href="https://github.com/apple/swift-corelibs-foundation/blob/ea6179dd35be2c7d9a8f953579f626a5f1be6511/CoreFoundation/Base.subproj/CFRuntime.c#L1773">finalize()</a> [2] function and hence through to <a href="https://github.com/apple/swift-corelibs-foundation/blob/ea3014bd7883e428727272118cbf37dc56522be6/CoreFoundation/Collections.subproj/CFData.c#L294">__CFDataDeallocate()</a> [3]. However, once in __CFDataDeallocate(), the code to free the buffer is skipped, because __kCFDontDeallocate is set.</div><div><br></div><div>If I hack _CFDataInit() so that __kCFDontDeallocate isn't set (by commenting out <a href="https://github.com/apple/swift-corelibs-foundation/blob/ea3014bd7883e428727272118cbf37dc56522be6/CoreFoundation/Collections.subproj/CFData.c#L337">this line</a> [4]) then I get crashes elsewhere - so this obviously isn't the right approach.</div><div><br></div><div>I can see that some work has been <a href="https://github.com/apple/swift-corelibs-foundation/commit/ea3014bd7883e428727272118cbf37dc56522be6">done in this area</a> [5] previously by Philippe so I'm wondering if anyone can advise on what might be going on here?</div><div><br></div><div>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.</div><div><br></div><div>Any help would be gratefully received!</div><div><br></div><div>Thanks,</div><div><br></div>[1] <a href="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</a><div>[2] <a href="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</a></div><div>[3] <a href="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</a><br><div>[4] <a href="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</a></div><div>[5] <a href="https://github.com/apple/swift-corelibs-foundation/commit/ea3014bd7883e428727272118cbf37dc56522be6">https://github.com/apple/swift-corelibs-foundation/commit/ea3014bd7883e428727272118cbf37dc56522be6</a><br clear="all"><div><br></div>-- <br><div class="gmail_signature">Ian Partridge<br></div>
<br></div></div></div>