Swift字典Absurd内存使用 [英] Swift Dictionary Absurd Memory Usage

查看:184
本文介绍了Swift字典Absurd内存使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的一个应用程序中遇到一个有趣的问题。许多次访问字典时,我的应用程序的内存使用量将超过一千兆字节。这里是一些示例代码来显示问题。

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

重复访问字典会导致内存爬升直到循环完成。我看着仪器,看到了大量的字符串分配。使用NSString的结果是这个问题。



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

 让nsKey =key1

同时将字典更改为NSDictionary可以解决问题:

  let dictionary:NSDictionary = [ key1:value1] 

有谁知道为什么使用cast NSString导致堆分配太多,除了上述之外还有其他修复?






这里是一些图片。看起来像幕后字符串被分配并设置为 autorelease (或者我正在读取下面的数据错误?)这可能是为什么内存使用不断分配,然后在以后排水?如果这是真的,应该被认为是错误?这个问题发生在OS X和iOS上。





解决方案

最佳解决方案是不要桥接到 NSString 这里。只需使用Swift类型。或者,如您所发现的,您可以使用基础类型( NSString NSDictionary )。桥接可能需要临时复制。



无论如何,尽管如此,在这样的循环中,由于某种原因创建临时副本非常常见(即使您避免了这种情况特别的问题)。为了解决这个问题,您需要在循环中排除自动释放池。例如:

  let dictionary = [key1:value1] 
let nsKey:NSString =key1
let swiftKey = nsKey as String
for _ in 0 ... 10000000 {
autoreleasepool {//< ===当前池的范围
字典[swiftKey ]
}
}

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


I ran into an interesting problem in one of my applications. When accessing a Dictionary many times, the memory usage of my application skyrockets to over a gigabyte in seconds. Here is some sample code to show the problem.

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

Repeatedly accessing the dictionary causes memory to climb until the loop finishes. I looked at instruments and saw tons of string allocations. Turns out using an NSString is the issue.

Changing the nsKey to a swift String like so fixes the issue:

let nsKey = "key1"

Also changing the dictionary to an NSDictionary fixes the issue:

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

Does anyone know why accessing the dictionary using a casted NSString causes so much heap allocation, and are there any other fixes besides the ones described above?


Here are some pictures. It looks like behind-the-scenes strings are being allocated and set to autorelease (or am I reading the data below wrong?) Could this be why memory usage continuously allocates and then drains at a later point? If this is true, should this be considered a "bug"? This issue occurs on OS X as well as iOS.

解决方案

The best solution is to not bridge to NSString here. Just use Swift types. Or, as you discovered, you can just use Foundation types (NSString and NSDictionary). Bridging can require making temporary copies.

In any case, though, in loops like this it's very common to create temporary copies for one reason or another (even if you avoided this particular problem). To address that, you need to drain your autorelease pool in the loop. For instance:

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]
    }
}

Adding that will keep your memory steady. This is a very common thing to do in large loops in Cocoa. Otherwise the pool won't be drained until you return from your top-level method.

这篇关于Swift字典Absurd内存使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆