gpt4 book ai didi

objective-c - NSXMLParser 不释放分配?

转载 作者:行者123 更新时间:2023-11-28 09:18:14 25 4
gpt4 key购买 nike

读取大型 XML 文件(几 GB)时,Swift 程序不断消耗内存,直到我的整个系统崩溃。不好。在四处挖掘并删除所有有用的代码之后,下面的代码仍然存在。它只定义了一个 NSXMLParserDelegate,在其上实现了一种协议(protocol)方法。现在,当针对 17 MB 的相对较小的 XML 文件运行时,总分配量将达到 47 MB​​,脏内存占 77 MB。现在这让我觉得很奇怪,因为我的代码没有引用它传递的任何数据。

这是 NSXMLParser 的错误、我的误解还是我的代码错误?

import Foundation

var input = NSURL(fileURLWithPath: Process.arguments[1])!
class MyDelegate: NSObject, NSXMLParserDelegate {
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: NSDictionary) {
}
}

var parser = NSXMLParser(contentsOfURL: input)!
var delegate = MyDelegate()
parser.delegate = delegate

parser.parse()

Allocations instrument VM Tracker instrument

文档

Memory management becomes a heightened concern when you are parsing XML. Processing the XML often requires you to create many objects; you should not allow these objects to accumulate in memory past their span of usefulness. One technique for dealing with these generated objects is for the delegate to create a local autorelease pools at the beginning of each implemented delegation method and release the autorelease pool just before returning. NSXMLParser manages the memory for each object it creates and sends to the delegate. (source)

更新

当直接使用 libxml2 的 sax 解析器时,内存使用量在几秒钟后保持稳定,使用量约为 100 MB。为什么 NSXMLParser(主要只是一个包装器)使用这么多内存?

更新 2

NSXMLParser 不应在代理处理完数据后保留数据。大多数由 NSXMLParser 分配的结构的引用计数为 1(见屏幕截图),因此保持分配状态。手动释放内存有帮助,但这与文档中的内存声明相矛盾并且感觉不对。

Malloc - ref count 1

最佳答案

根据实验,我认为 NSXMLParser 确实使用了全局 autoreleasepool。所以 autoreleasepool 只管理整个解析事件,而不是对委托(delegate)的单独回调。因此在解析文件时内存压力会增加,只有在解析完整个文件后才会释放内存压力。

伪代码:

Call function parse
@autoreleasepool {
Call delegate function with NSDictionary {
Bridge NSDictionary to Swift dictionary
Call my Swift delegate with Swift dictionary {
// my code
}
}
}
}

因此,NSDictionary 和桥接的 Swift 字典都保留在堆上,直到解析函数完成。为了减少内存压力,不要使用 Swift 委托(delegate),因此堆上没有 Swift 字典。或者,远离 NSXMLParser 并实现 libxml 的 sax 解析器并包含更多 autoreleasepool

关于objective-c - NSXMLParser 不释放分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26514909/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com