2016-12-23 10 views
0

構造体の文字列データを収集しています。最後に、その文字列をファイルに書き込んでいます。結果は、各80 MBの4つのファイルです。しかし、それはRAMの16GB(!)近くを占めており、OSは強制的にスワップします。 (私はSwift 3.0を使用しています)巨大なメモリ消費(文字列)

struct ActionCMD { // struct! 
    var cmd = String() 

... 

    mutating func lines(_ text: String, toTheTop: Bool = false) { 
     if toTheTop { cmd = text + cmd } 
     else  { cmd += text } 
    } 
... 
} 

なぜこのようなことが起き、避けるべきなのでしょうか?

+1

あなたはどこかでメモリリークがあるように見えます。インストゥルメントを起動し、すべてのメモリを何が使用しているか確認しましたか? –

+0

いいえ、ツールはわかりません。私はそれを探していて(そして使い方も)、その問題を調べようとしています。 –

+0

もちろん、それは方法ですが、あなたのアーキテクチャに害を及ぼさないなら、 'ActionCMD'を' class'として書き直すことができます。 – Leo

答えて

1

おそらく、mutatingとマークされた方法と関係があります。 Swiftのmutatingメソッドは、この場合はActionCMDインスタンスの新しいコピーに変更を適用します。残りのコードによっては、それらのインスタンスをすべて保持している可能性があります。

+0

それは面白いです。私は構造体内の文字列を変更しているので、変更しています。この効果なしでこれを行う別の方法がありますか?(!)それを素早く保ちますか?構造体からクラスへの切り替えがこれをさらに悪化させますか?私は自分自身を変えるのではなく、もっと多くのオブジェクトを作成しないので、そうではないかもしれません。 –

+0

Swiftの構造体は値型です。これはユースケースを非常にうまくサポートしていないようです。 'ActionCMD'をインスタンス変数' var cmdComponents:[String] = [] 'を持つクラスにすることができます。その配列を正しい順序ですべての文字列で埋めると、 'cmdComponents.reduce(" "、combine:+)'で単一の文字列を作ることができます。 –

+0

ありがとうございます。私はクラスを行い、配列を使いました。それはメモリ消費量を半減させるようです。まだ8,5 GB !?しかし、それ以上の最適化は見られません。 –

-1

C#とJavaでは、あなたがしなければ何かを追加するたびに新しい文字列が作成されるので、stringbuilderを使用します。 stringbuilderはメモリを1回だけ割り当てます。

これは:http://cocoadocs.org/docsets/StringBuilder/は、JavaからSwiftへのポートであるようですが、テストしていませんが、試してみてください。

この1つ:https://gist.github.com/kristopherjohnson/1fc55e811d944a430289は非常に悪い(Googleの最初の結果は悲しいことです)。これは文字列ビルダではなく、通常のメソッドを包むラッパーです。

0

まず、これらのインスタンスの割り当て方法と割り当て解除方法を知らなくても、アプリケーションで何がうまくいかないかを伝えるのは非常に難しいです。表示されている問題は、保持サイクルや文字列データの収集方法に関連している可能性があります。文字列は値型であるため、変更するたびにコピーオンライト機能により新しいコピーが作成されます。つまり、ObjCとSwiftを使用してメモリ管理を改善するためのいくつかのヒントについては、good articleを参照してください。お役に立てれば。

関連する問題