I have an app that has a problem with memory leaks. After using various tools, I narrowed the leak down to a ByteCountFormatter
.
I have created a very simple unit test to check the code:
import XCTest
final class DiskUtilitiesTests : XCTestCase
{
let formatter = ByteCountFormatter()
func testMemoryLeaks() {
self.formatter.allowedUnits = .useBytes
self.formatter.includesUnit = true
for i in 0 ..< UInt64.max {
let string = self.formatter.string(fromByteCount: Int64(i))
}
}
}
When running the unit test, the memory increases very fast. The code seems very simple, so I do not understand why the memory consumption increases at all. At first I thought that the memory of the string variables is freed once the for loop exits, but this is not the case. Even when the scope is left (for loop is exited), the memory is not freed.
As an additional test, I added the call to the formatter to a autoreleasepool
:
import XCTest
final class DiskUtilitiesTests : XCTestCase
{
let formatter = ByteCountFormatter()
func testMemoryLeaks() {
self.formatter.allowedUnits = .useBytes
self.formatter.includesUnit = true
for i in 0 ..< UInt64.max {
autoreleasepool {
let string = self.formatter.string(fromByteCount: Int64(i))
}
}
}
}
Now the memory consumption is constant (both in Xcode and Activity Monitor). What is the explanation for this behaviour?