

AudioUnit
を使って音声の録音、再生を行なうプログラムを作成しているのですが、以下のようなバグに遭遇しました。色々手を尽くしては見たものの一向に改善しなかったため、質問させていただきます。

録音側のAURenderCallbackStructに設定したコールバック関数 `AURenderCallback` 内中段の `NSMutableData
*data` でメモリリークを起こしているようです。(`Instruments` の`Allocations`
はずっと右肩上がりになっています：2.5KB/秒)

色々調査した結果分かった事↓です。

  * (中略) 部分を削除しても現象に変化はありません
  * `AudioProcessor *rec`、`OSStatus status` の行を削除しても現象に変化はありません
  * `NSMutableData *data` を削除すると `Allocations` はすぐに一定になります
  * `NSMutableData *data` を `int` や `NSData`, `NSArray` に変更すると `Allocation` はすぐに一定になります。
  * `NSMutableDataやNSMutableArray`, `NSObject` では `Allocation` は一定にならず上昇をし続けたままになります
  * この現象はiPad mini (iOS 7.0.4) でのみ確認できていて、iPhone 4s (iOS7.1.1) では発生しませんでした。

[code]

    OSStatus AURenderCallback(void *inRefCon,
                             AudioUnitRenderActionFlags *ioActionFlags,
                             const AudioTimeStamp *inTimeStamp,
                             UInt32 inBusNumber,
                             UInt32 inNumberFrames,
                             AudioBufferList *ioData)
    {    
        AudioProcessor *rec = (__bridge AudioProcessor *) inRefCon;
    
        OSStatus status = AudioUnitRender([rec audioUnit], ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &testbufferList);
    
    
        NSMutableData *data = [[NSMutableData alloc] init];
        /*
            ~(中略)~
        */
        return noErr;
    }
    
[/code]

以上、ご教示ください。


CC BY-SA 3.0
2015-06-09T08:00:57.577
11172
2015-08-05T01:20:15.877
2015-06-09T08:13:23.793
76
10065
question
objective-c iphone
NSMutableDataのインスタンスがiPad(iOS7.0.4)でのみリークする


私はMacのAudioUnitはそれなりに知っていますがObjective-Cの  
メモリ管理システムにはあまり詳しくない、という者です。

で、このソースは一見しただけでリークしそうな感じがする実装になっています。  
allocは、メモリを確保するためのメソッドなので、呼ばれるたびに  
メモリを確保しますが、開放されている様子がないからです。  
AURenderCallbackはかなりの頻度で実行されるので  
メモリ使用量が増えていくだろうな、というのがソースをみただけで想像できます。

そもそも、AURenderCallback内でメモリ確保の処理を実行するのは  
あまり良い戦略ではないので、NSMutableData* dataをAURenderCallback内で  
はallocしないように処理を修正することをおすすめします。

やり方はいろいろとあると思いますが、私ならばAURenderCallbackの引数として渡されてくる  
AudioProcessor側でallocしておき、AURenderCallbackで使うように実装します。  
このソースからだとAURenderCallback以外の部分がどうなっているか不明なので、  
具体的なソースは書きませんが、AURenderCallback内ではメモリ確保の処理はできないことを  
前提にプログラムを書いたほうが良いことが多いです。


CC BY-SA 3.0
2015-07-06T00:40:59.673
12060
2015-07-06T00:40:59.673
10410
11172
answer