2016-09-17 34 views
1

初めてSceneKitとSpriteKitとARCを使用してアプリケーションを作成し始めました。私は、異なるビュー間で切り替えると、メモリ使用量が急速に増えていることに気付きました。私の最初の考えは、私はメモリリークがあったが、私は今確信していない。動作も、この基本的な例で発生します。メモリが完全に解放されていない

for(int r=0;r<9999999;r+=1){ 
    NSString *s=[NSString stringWithFormat:@"test%i",r]; 
    s=nil; 
} 

私の理解から、NSStringのオブジェクトが作成され、直接このループで放出されます。私はこの例をiPhone-SimulatorとiPhoneで試してみました。このループが実行された後、アプリは数百MBのRAMを使用します。 (私はXcodeデバッグナビゲータでメモリ使用量をチェックしています)

私は明らかに何かを誤解しています。なぜこの例はまだメモリを保持していますか?

編集:

また、新しいプロジェクトを作成することができます。その後のviewDidLoadにこれを追加しSceneKit

:iOS版 - - >ゲーム>ゲームテクノロジーを

for(int r=0;r<999999;r+=1){ 
    SCNNode *tn=[SCNNode node]; 
    tn=nil; 
} 

メモリを意志550MBでピークに達し、オブジェクトが完全に解放されてRAMから削除された場合は300MBになります。

+1

ところで、あなたはメモリの圧力をシミュレートしようとするかもしれません。 Cocoaオブジェクトはあらゆる種類のキャッシングを行いますが、その中にはメモリ警告があるときにパージされるものもあります。また、あなたのスキームでメモリデバッグオプション(特にゾンビ)をオンにした場合、メモリがさらに増加し​​、リーク、放棄、またはキャッシュメモリを分析する前にそれらをオフにしたい場合があることに注意してください。 – Rob

+0

この問題を解決してくれてありがとう。私はゾンビをオンにしていませんでしたが、あなたのアドバイスによってすべてのデバッグ設定が無効になり、問題が解決しました。したがって、この問題はすべてデバッグ機能に関連しています。 – KugelnMMXVI

+0

優れています。私はそれを私の答えに組み込んだ。 – Rob

答えて

1
  1. メモリ診断にはNSStringを使用しないでください。それはかなり非典型的な振る舞いをしている。

    これは、私がS.O.で見たことのある珍しいことではないシナリオです。いくつかの複雑なメモリ問題をより簡単なものにするために、NSStringを使用して簡単な例を作成し、その特定のクラスを選択することで不思議で無関係な動作が発生することに気づかないことがあります。新しい「デバッグメモリグラフ」ツールまたは古い試行錯誤ツール(下記参照)は、コード内の根本的な問題を診断する最善の方法です。

  2. ただ、オブジェクトをすぐに解放する方法について説明します。あなたのメソッドがallocnewcopyまたはmutableCopyで始まらない場合、オブジェクトはautoreleaseオブジェクトなので、範囲外になった直後にでなくが割り当て解除されます。自動解放プールがなくなるまで(たとえば、実行ループに戻る)、それらは解放されません。

    アプリの「高水準」マークが高すぎますが、メモリが最終的に許容レベルに戻った場合、自動リリースオブジェクトの選択(および/または独自の自動解放プールの導入)を検討してください。しかし、一般に、このオートリリースと非オートリリースオブジェクトの区別は、実行ループに戻る前に多くのオブジェクトを割り当てる非常に長い実行ループがない限り、幾分学術的です。手短に言えば、自動解放オブジェクトは、オブジェクトが割り当て解除されているかどうかに影響を与えませんが、割り当てが解除されたときにのみ影響します。大規模なforループとオブジェクトの即座に割り当てを解除するという競合に対応してこれを言及します。割り当て解除の正確なタイミングは、オートリリースオブジェクトの存在によって影響を受けます。

  3. あなたのアプリの急速なメモリの増加に関しては、ここの例とまったく無関係である可能性が高いです。これを診断する方法は、Instruments(WWDC 2013 Fixing Memory Issuesで説明されているように)を使用することです。要するに、「製品」 - 「プロファイル」を選択し、「漏れ」ツール(必須の「割り当て」ツールも同様に)を選択し、アプリケーションを実行し、割り当てられたものとリリースされなかったものを正確に調べます。

    また、Xcode 8の「デバッグオブジェクトグラフ」ツールも非常に便利で、さらに使いやすくなっています。それは、WWDC2016のVisual Debugging with Xcodeに記載されています。このツールを使用すると、左側のパネルにオブジェクトのリストが表示され、そのオブジェクトに関連付けられたオブジェクトグラフが表示されるので、未解決の参照をまだ診断できます。

    enter image description here

  4. ところで、メモリ警告のシミュレーションを試してみるとよいでしょう。 Cocoaオブジェクトはあらゆる種類のキャッシングを行いますが、その中にはメモリ不足のときにパージされるものもあります。

  5. スキームのメモリデバッグオプション(ゾンビなど)を有効にした場合、関連付けられたデバッグ情報をキャプチャする際にメモリが増加することに注意してください。リークされた、放棄された、またはキャッシュされたメモリを分析する前に、デバッグオプションをオフにしたい場合があります。あなたが現れているインスタンスオブジェクトの反復あたりのキロバイトのカップルの成長とどれを見ていると、あなたが持っていない場合

ボトムライン、任意のデバッグオプションは、あなたがないかもしれないが、オンそれを心配する必要があります。多くのCocoaオブジェクトは、私たちのコントロールの外にある雑多なキャッシュを行っています。通常は無視できます。しかし、メモリがすべての反復でmbまたはgbずつ増加している場合(最初の反復については心配しないでください)、それは本当に注意深く見なければならないものです。

+0

1. NSStringは、単純化のために選択された単なる例です。私のアプリでは、もともと私のカスタムSceneKitビューと同じでした。この例では、次の行で同じ結果が得られます。SCNScene * s = [SCNScene scene]; – KugelnMMXVI

+0

2.それは私が探していたものかもしれません。私はこのトピックをさらに詳しく見ていきます。 – KugelnMMXVI

+0

3.私はすでにこれらのツールを使用しており、リリースされていないオブジェクトを見つけるのは簡単です。これは私がこの短いループの例に私の観察を取り除いた方法です。しかし、これらのNSStringsやSCNScenesはそこにはリストされておらず、まだメモリを取っています。私の例は完全に人工的であることに注意してください。ループはそこにありますので、かなりの量のメモリを追加します。 – KugelnMMXVI

関連する問題