0

大きなオブジェクト グラフ (76295 オブジェクト) をエンコードするために NSKeyedArchiver を使用しています。多くの時間がかかりますが、さらに悪いことに、NSKeyedArchiver はすべてのメモリを返してくれません。

リーク チェックを使用した後、コードはまったくリークしていないように見えますが、何らかの理由で、エンコードが完了した後にすべてのメモリが返されません。

エンコード メソッドを数回呼び出すとさらに悪化し、ますます多くのメモリが消費されます。

私が好きな提案はありますか?

PS データベース (sqlite) または CoreData は、上記のような大きなオブジェクト グラフではスケーリングが非常に不十分であるように見えるため、代替手段ではありません。

NSKeyedArchiver を使用したソリューションを希望します

4

2 に答える 2

1

NSKeyedArchiver は、実際にはオブジェクトをエンコードしません。グラフをウォークし、グラフ内の各インスタンスのエンコード メソッドを呼び出すだけです。したがって、リークの原因として最も可能性が高いのは、カスタム クラスの 1 つをアーカイブするために作成したカスタム コーダー メソッドの内部です。個々のクラスのテスト アーカイブを実行して、そのうちの 1 つがリークするかどうかを確認することをお勧めします。

NSKeyedArchiver を使用して大規模で複雑なグラフをアーカイブする際の問題は、グラフ全体が一度にメモリに積み上げられることです。そのクラスの多くのインスタンスがアーカイブされている場合、1 つのクラス コーダーで 1 つのリークが爆発する可能性があります。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 に答える