首页 > 解决方案 > 当我测试它时,NSCache 在内存压力下不会删除项目,但是文档说它确实

问题描述

这是我在文档中看到的。

NSCache 类结合了各种自动驱逐策略,确保缓存不会使用过多的系统内存。如果其他应用程序需要内存,这些策略会从缓存中删除一些项目,从而最大限度地减少其内存占用。

但是当我查看源代码时:https ://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSCache.swift

在内存压力下,我看不到它会以某种方式删除项目。它仅在您达到成本限制时删除项目。

我做了一个小测试:

class Data {
    var data = [Int]()

    init() {
        for i in 0..<1000000 {
            data.append(i)
        }
    }
}

var cache = NSCache<NSNumber, Data>()

for i in 0..<10000000 {
    cache.setObject(Data(), forKey: NSNumber(value: i))
}

在那次测试之后,应用程序会吃掉所有的内存并崩溃。所以。文件是谎言吗?

标签: iosswiftcaching

解决方案


首先,也是最重要的,swift-corelibs-foundation 不是 iOS 和 macOS 的 Foundation:

这个项目 swift-corelibs-foundation 为没有 Objective-C 运行时的平台提供了 Foundation API 的实现。在 macOS、iOS 和其他 Apple 平台上,应用程序应使用操作系统附带的 Foundation。我们的目标是让这个项目中的 API 与 OS 提供的 Foundation 相匹配,并尽可能抽象出确切的底层平台。

接下来,您的测试用例没有仔细测试NSCache。您的Data对象可以存储在自动释放池中并且不会被释放。在这种情况下,这是不正确的,但这是您在测试内存使用情况时需要非常小心的事情。

也就是说,我无法重现您的问题。当我将它放入 iOS 应用程序并在 iOS 12 上运行时,我看到了您可能期望的那种行为:

在此处输入图像描述

内存使用量大幅上升至约 1GB,此时缓存按预期转储。

我也无法在 macOS 上轻松重现它(但我没有足够的耐心让它崩溃,所以它最终可能会崩溃)。您需要给出一个更精确的示例来说明意外崩溃的位置,以便诊断原因。


推荐阅读