数据不会在 swift 中被 ARC 删除

问题描述 投票:0回答:1

我有一个

for-loop
,它会执行一些操作并在执行期间分配大约 200MB 的空间。 即使在 for 循环执行几分钟后,数据也不会被释放。 它只会更改数据,不会创建随后需要存储的新数据。

这是我的代码:

   func mutateNetwork(){
        let conCount = currentWorkflowHolder.workflowData[currentWorkflowHolder.workflowData.count-1][currentWorkflowHolder.workflowData[currentWorkflowHolder.workflowData.count-1].count-1].thirdConnections.count-1
        for _ in 0...50{
            let arg1 = Int.random(in: 0...conCount)
            
            let arg2 = Int.random(in: 0...currentWorkflowHolder.workflowData[currentWorkflowHolder.workflowData.count-1][currentWorkflowHolder.workflowData[currentWorkflowHolder.workflowData.count-1].count-1].thirdConnections[conCount].count)
            currentWorkflowHolder.workflowData[0][0].thirdConnections[arg1][arg2] = Float.random(in: -50...50)
        }
        
    }

由于我试图消除潜在的问题,所以有点混乱。

我已经尝试过:

  • 使用
    autoreleasepool{}
    ,但没有帮助
  • 我发现的其他解决方案似乎专注于在循环中释放 RAM(但它不起作用)

编辑: currentWorkflowHolder 是一个属性,但它没有 get{} 或 set{}。

swift for-loop heap-memory
1个回答
0
投票

它仅更改数据,不会创建事后需要存储的新数据。

这可能并不像您想象的那样。这段代码几乎肯定会进行大量的分配和复制。该代码的高度简化版本是:

xs[1][2] = 4 

这不是一个“二维数组”,您只是修改其中的单个元素。这是一个数组的数组,您正在修改嵌套数组 包含数组。它的工作原理大致如下:

var row = xs[1]
row[2] = 4  // This is **very** likely to make a copy of all of row.
xs[1] = row // This will probably make a copy of all of xs.

考虑到这里发生的所有嵌套,您几乎肯定会复制所有内容的副本。这些最终都应该被释放,这样这只代表短期内存峰值和非常糟糕的性能。

当您说“数据不会被释放”时,您如何检查这一点?如果您只是查看报告的总内存使用情况,这是正常的。当你的程序分配内存然后释放它时,如果没有内存压力,它可能不会立即返回到操作系统。这是一种优化,因为从操作系统请求内存是昂贵的,并且系统假设如果您请求一次,您可能会再次需要它。 Instruments 中的分配工具通常是检查内存使用情况的更好方法。 Xcode 的内存“仪表板”通常也非常适合此目的。但像活动监视器这样的东西可能会产生极大的误导。

解决此问题的方法是重新设计数据存储。作为一个起点,如果这实际上是一个矩阵而不是任意长度数组的数组,那么实现它的正确方法是一个单一的平面数组,您可以通过将行乘以宽度来计算索引,然后添加列(或反之亦然,具体取决于您想要的顺序)。

© www.soinside.com 2019 - 2024. All rights reserved.