在快速应用程序中,内存不断增加

问题描述

我正在编写一个通用的Swift应用程序(不适用于iOS,它将稍后在raspbian上运行),并且我发现内存不断增加。我还通过检查器检查了内存泄漏,但没有。 为了更深入地了解,我为macOS创建了一个空白应用程序,我只编写了这些代码行,仅用于测试:

var array = [Decimal]()

while(true) {
    array = [Decimal]()
    for i in 0..<10000
    {
        array.append(Decimal(string: i.description)!)
    }
    sleep(1)
}

据我所知,在while循环的每个循环开始时,应将上一个循环中填充的整个数组从内存中删除。但是似乎这并没有发生,因为这些代码行会无限期地增加进程内存。

我还在iOS项目上尝试了相同的代码,并将其放在应用程序功能上(在应用程序委托的开头调用的那个),我注意到在这种情况下,内存保持不变并且不会上升

我是否在非iOS项目中丢失了某些内容

解决方法

Decimal(string:)正在创建自动释放对象。使用autoreleasepool定期清空池:

var array = [Decimal]()

while true {
    autoreleasepool {
        for i in 0..<10_000 {
            array.append(Decimal(string: i.description)!)
        }
        sleep(1)
        array = []
    }
}

通常,当您退回到运行循环时,自动释放池就会耗尽。但是在这种情况下,此while循环永远不会退回到OS,因此池不会耗尽。如上所述,使用您自己的autoreleasepool可解决该问题。

FWIW,Apple一直在Foundation / Cocoa类中逐渐取消使用自动释放对象。 (我们过去使用比现在更多的Foundation对象/ API来遇到此问题。)显然,Decimal(string:)仍在幕后创建自动释放对象。在大多数实际情况下,这不是问题,但是在您的示例中,您需要引入自己的autoreleasepool来减轻此while循环中的这种行为。