使用 NSKeyedArchiver 编码大型对象图会占用内存
我正在使用 NSKeyedArchiver 来编码大对象图(76295 个对象。) 这需要花费很多时间,但更糟糕的是 NSKeyedArchiver 不会归还其所有内存。
使用泄漏检查后,代码似乎根本没有泄漏,但由于某种原因,编码在完成后没有返还所有内存。
多次调用encode方法确实会让情况变得更糟,越来越多的内存被吃掉。
你有什么建议我可以喜欢吗?
PS 数据库(sqlite)或 CoreData 不是替代方案,因为它们对于像上面提到的那样的大对象图来说似乎扩展性很差。
我更喜欢使用 NSKeyedArchiver 的解决方案
I'm using a NSKeyedArchiver to encode a big object graph (76295 objects.)
It takes a lot of time but even worse the NSKeyedArchiver doesn't give back all its memory.
After using the Leak check, the code doesn't appear to leak at all but for some reason the encoding doesn't give back all memory after it's done.
Calling the encode method several times does make it worse, more and more memory is being eaten away.
You got any suggestions I could like at?
P.S. A database (sqlite) or CoreData aren't alternatives because they seem to scale very poorly with an big object graph like the one mentioned above.
I would prefer a solution using NSKeyedArchiver
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
NSKeyedArchiver 实际上并不对对象进行编码。它只是遍历图表并调用图表中每个实例的编码方法。因此,最有可能的泄漏源是您为归档自定义类之一而编写的自定义编码器方法内部。您可能想要对各个类进行测试存档,以查看其中之一是否泄漏。
使用 NSKeyedArchiver 归档大型复杂图的问题是整个图会立即堆积到内存中。如果该类的大量实例被归档,则该类编码器中的一次泄漏可能会爆炸。如果您有 76,000 多个对象,而其中只有几千个对象每个泄漏几个字节,那么这些对象很快就会加起来。
我必须补充一点,我从未遇到过,甚至读过这样的情况:无论大小如何,核心数据的性能都不比复杂图形的存档更好。 Core Data 就是专门为了处理此类问题而创建的。
如果您尝试过 Core Data 并且陷入困境,可能是因为您习惯了很多实体继承。由于 Core Data 在 SQL 的存储端使用单表继承,因此实体的所有后代最终都会出现在同一个表中,这会使事情陷入困境。请记住,实体与其建模的类是分开的,因此您可以拥有类继承而无需实体继承。这为您提供了继承的编码优势,而没有实体继承的速度损失。
NSKeyedArchiver doesn't actually encode objects. It simply walks the graph and calls the encode methods of each instances in the graph. Therefore, the most likely source of a leak is inside a custom coder method that you wrote to archive one of your custom classes. You might want to do test archives of individual classes to see if one of them leaks.
The problem with using NSKeyedArchiver to archive a large complex graph is that the entire graph is piled into memory at once. One leak in one classes coder can explode if a lot of instances of that class are archived. If you have 76,000+ objects and just a couple of thousand leak a few bytes each, that will add up in a hurry.
I must add that I have never encountered or even read of a situation in which Core Data did not perform better than an archive for complex graphs regardless of size. Core Data was created specifically to handle just this sort of problem.
If you've tried Core Data and it bogged down, it is probably because you used to much entity inheritance. Since Core Data uses single table inheritance on the store side in SQL, all the descendants of an entity end up in the same table and that bogs things down. Remember, entities are separate from the classes they model so you can have class inheritance without having entity inheritance. That gives you the coding advantages of inheritance without the speed penalty of entity inheritance.
似乎内存会在稍后的时间间隔慢慢地返回给系统。
所以不存在真正的内存泄漏。
对于其他人:尝试直接查看 CoreData 或 sqlite3。
如果直接使用 sqlite3,请确保将完整的查询集封装在事务中;它将显着提高数据吞吐量。
有关 sqlite 速度优化的更多信息:
http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html< /a>
Seems the memory is given back to the system slowly at a later interval.
So no real memory leak is there.
For anyone else: try look at CoreData or sqlite3 directly.
If you use sqlite3 directly make sure you encapsulate the complete set of queries in an transaction; it will dramatically increase data throughput.
More info regarding sqlite speed optimization:
http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html