如何强制释放内存

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

我正在尝试迭代大型文件树以读取 URL 并创建哈希值,但存在无法修复的内存泄漏。消耗的内存不断增加,直到应用程序停止工作。出于测试原因,我尝试读取 600Gb/350T 文件并对其进行哈希处理,其中单个文件高达 25Gb,将 URL 和哈希值写入一个简单的文本文件。生产数据约为 50-70Tb/180 万个文件。

我读了很多文章和帖子,了解了“autoreleasepool”,但到目前为止没有任何效果。散列文件所消耗的内存没有被释放,并且应用程序内存堆栈快速增长。

func readWrite(_ url: URL) {
        
        let enumerator = FileManager().enumerator(at: url, includingPropertiesForKeys: [.isRegularFileKey])
        
        while let element = enumerator?.nextObject() as? URL {
            do {
                if element.isFileURL {
                    let data = try Data(contentsOf: element)
                    let hash = createFileHash(element)
                    
                    let stringData = Data("\(hash),\(element.description)\n".utf8)
                    write(stringData, url)
                }
            } catch {
                print("\(error.localizedDescription)")
            }
        }
    }
    
    private func createFileHash(_ url: URL) -> Int {
        autoreleasepool {
            guard let data = try? Data(contentsOf: url) else { return 0 }
            return data.hashValue
        }
    }
swift memory-management
1个回答
0
投票

您对

autoreleasepool
的使用成功释放了您在
Data(contentsOf: url)
中创建的
createFileHash
。但是,您的
while
循环中还有两行创建
Data
对象:

let data = try Data(contentsOf: element)
// and
let stringData = Data("\(hash),\(element.description)\n".utf8)

第一行创建的

Data
没有被释放。您似乎也没有使用这个
data
变量,所以您可以删除这一行。对于这个答案的其余部分,我将假设这不是您的完整代码,并且您do在某个地方使用它。

第二行创建的

Data
完全是一个 Swift 对象,所以据我所知,它会像所有其他 Swift 对象一样被正常释放。

您应该用

autoreleasepool
包裹整个while循环体,并且可以删除
autoreleasepool
中的
createFileHash
(假设这是您调用
createFileHash
的唯一地方)。

while let element = enumerator?.nextObject() as? URL {
    autoreleasepool {
        do {
            if element.isFileURL {
                let data = try Data(contentsOf: element)
                let hash = createFileHash(element)
                
                let stringData = Data("\(hash),\(element.description)\n".utf8)
                write(stringData, url)
            }
        } catch {
            print("\(error.localizedDescription)")
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.