0

我正在使用 NSKeyedArchiver 对大对象图(76295 个对象)进行编码。这需要很多时间,但更糟糕的是 NSKeyedArchiver 并没有归还其所有内存。

使用泄漏检查后,代码似乎根本没有泄漏,但由于某种原因,编码完成后不会返回所有内存。

多次调用 encode 方法确实会使情况变得更糟,越来越多的内存被消耗掉。

你有什么我喜欢的建议吗?

PS 数据库 (sqlite) 或 CoreData 不是替代品,因为它们似乎与上面提到的大对象图的扩展性很差。

我更喜欢使用 NSKeyedArchiver 的解决方案

4

2 回答 2

1

NSKeyedArchiver 实际上并不编码对象。它只是遍历图并调用图中每个实例的编码方法。因此,泄漏的最可能来源是您编写的用于归档您的自定义类之一的自定义编码器方法。您可能想要测试各个类的存档,以查看其中一个是否泄漏。

使用 NSKeyedArchiver 归档大型复杂图的问题是整个图一次堆积到内存中。如果归档了该类的许多实例,则一个类编码器中的一次泄漏可能会爆炸。如果您有 76,000 多个对象,并且每个对象只有几千个泄漏几个字节,那么这将很快加起来。

我必须补充一点,我从来没有遇到过甚至读过这样的情况,即无论大小如何,Core Data 的性能都不如复杂图形的存档。Core Data 是专门为处理此类问题而创建的。

如果您尝试过 Core Data 并且它陷入了困境,那可能是因为您习惯了很多实体继承。由于 Core Data 在 SQL 的存储端使用单表继承,一个实体的所有后代最终都在同一个表中,这使事情陷入困境。请记住,实体与它们建模的类是分开的,因此您可以在没有实体继承的情况下进行类继承。这为您提供了继承的编码优势,而没有实体继承的速度损失。

于 2010-02-15T19:58:24.363 回答
0

似乎内存在稍后的时间间隔缓慢地归还给系统。所以没有真正的内存泄漏。

对于其他人:尝试直接查看 CoreData 或 sqlite3。如果您直接使用 sqlite3,请确保将完整的查询集封装在事务中;它将显着提高数据吞吐量。

有关 sqlite 速度优化的更多信息: http ://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html

于 2010-03-24T14:18:28.107 回答