The problemPlease check out following macOS console app and advice how to prevent memory footproint growth (leakage) caused by SecItemCopyMatching: ...
let service = "SampleService"
func composeQuery() -> [String: Any] {
return [kSecClass as String: kSecClassInternetPassword,
kSecAttrServer as String: service,
kSecMatchLimit as String: kSecMatchLimitOne,
kSecReturnAttributes as String: true,
kSecReturnData as String: true]
}
func save(value: String) {
let encodedValue = value.data(using: String.Encoding.utf8)!
var query = composeQuery()
query[kSecValueData as String] = encodedValue
SecItemAdd(query as CFDictionary, nil)
}
autoreleasepool {
save(value: "SomeValue")
}
for _ in 0..<20000 {
let query = composeQuery()
// UNCOMMENT here - no leak
_ = autoreleasepool {
//######################
// THE PROBLEM IS HERE
//######################
SecItemCopyMatching(query as CFDictionary, nil)
//######################
// THE END
//######################
}
}
...There are no leaks according to instruments. But I see in Activity Monitor, memory footprint keep growing and eventially almost all is going to swap.https://github.com/botov/KeychainOSXLeak/blob/master/Leak.pngAccording to vmmap: VIRTUAL RESIDENT DIRTY SWAPPED VOLATILE NONVOL EMPTY REGION
REGION TYPE SIZE SIZE SIZE SIZE SIZE SIZE SIZE COUNT (non-coalesced)
VM_ALLOCATE 78.1M 0K 0K 78.1M 0K 0K 0K 647Accoring to my observations each SecItemCopyMatching costs aprox 4KB of leaked (abandoned and swaped) memory. So if you increase the main loop iterations from 20 000 to 200 000 => you will observe ~800MB of leaked memory.What's wrong with the SecItemCopyMatching usage?You can check the sample app yourself. For convenience I put code here:https://github.com/botov/KeychainOSXLeak