Swift Dictionary荒谬的内存使用

我在其中一个应用程序中遇到了一个有趣的问题。 当多次访问Dictionary ,我的应用程序的高速caching的内存使用量在几秒钟内就超过了千兆字节。 这里是一些示例代码来显示问题。

 override func viewDidLoad() { let dictionary = ["key1":"value1"] let nsKey: NSString = "key1" let swiftKey = nsKey as String for _ in 0 ... 10000000 { dictionary[swiftKey] } } 

反复访问字典会导致内存爬升,直到循环结束。 我看着仪器,看到了很多string分配。 原来使用NSString是这个问题。

将nsKey更改为像这样的swift String修复了这个问题:

 let nsKey = "key1" 

还将字典更改为NSDictionary可以解决此问题:

 let dictionary: NSDictionary = ["key1":"value1"] 

有谁知道为什么访问字典使用铸造的NSString导致如此多的堆分配,除了上面描述的还有其他修复吗?


这里有一些照片。 它看起来像幕后的string正在被分配和设置为autorelease (或者我读取错误的数据?)这可能是为什么内存使用不断分配,然后在以后的时间stream失? 如果这是真的,这应该被视为一个“错误”? 这个问题发生在OS X和iOS上。

在这里输入图像说明

在这里输入图像说明

最好的解决办法是不要在这里连接到NSString 。 只需使用Swifttypes。 或者,正如您发现的,您可以使用基础types( NSStringNSDictionary )。 桥接可能需要临时复制。

无论如何,在这样的循环中,由于某种原因创build临时副本是非常常见的(即使你避免了这个特殊的问题)。 为了解决这个问题,你需要在循环中消耗自动释放池。 例如:

 let dictionary = ["key1":"value1"] let nsKey: NSString = "key1" let swiftKey = nsKey as String for _ in 0 ... 10000000 { autoreleasepool { // <=== the scope of the current pool dictionary[swiftKey] } } 

添加这将保持你的记忆稳定。 在Cocoa的大循环中这是一件非常常见的事情。 否则,在从顶级方法返回之前,池将不会被排空。