【问题标题】:memory is growing in audio buffer code音频缓冲区代码中的内存正在增长
【发布时间】:2012-04-23 10:07:45
【问题描述】:

我有一个我们在应用程序中多次使用的代码,它是一个获取缓冲区样本并处理它的类,然后将通知发送回主类。 代码是c和objective-c。

它工作得很好,但是我可以在instruments-allocations 工具中看到内存在增长。 “总字节数”以每秒 100k 的速度不断增长。因为代码的某些部分我知道他们是谁

这是回调函数,带有产生问题的行。 它每秒发生很多次。 我也不太明白我的*pool 应该放在哪里:

    static OSStatus recordingCallback(void *inRefCon, 
                                      AudioUnitRenderActionFlags *ioActionFlags, 
                                      const AudioTimeStamp *inTimeStamp, 
                                      UInt32 inBusNumber, 
                                      UInt32 inNumberFrames, 
                                      AudioBufferList *ioData)
    {

        AudioBuffer buffer;
        buffer.mNumberChannels = 1;
        buffer.mDataByteSize = inNumberFrames * 2;
        //NSLog(@"%ld",inNumberFrames);
        buffer.mData = malloc( inNumberFrames * 2 );
        // Put buffer in a AudioBufferList
        AudioBufferList bufferList;
        bufferList.mNumberBuffers = 1;
        bufferList.mBuffers[0] = buffer;


        // block A
        OSStatus status;
        status = AudioUnitRender(audioUnit, 
                                 ioActionFlags, 
                                 inTimeStamp, 
                                 inBusNumber, 
                                 inNumberFrames, 
                                 &bufferList); 

       //end block A

         NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
        int16_t *q = (int16_t *)(&bufferList)->mBuffers[0].mData;
        int16_t average ;

        for(int i=0; i < inNumberFrames; i++)
        {


            average=q[i];   

            if(average>100) // lineB 
                reducer++;

           //blockC
            if(reducer==150 )
            {

                average= preSignal + alpha*(average-preSignal);
                //NSLog(@"average:%d",average);

                //call scene
                [dict setObject:[NSNumber numberWithInt:average] forKey:@"amp" ] ;
                [[NSNotificationCenter defaultCenter] postNotificationName:@"DigitalArrived" object:nil userInfo:dict];
                reducer=0;
                preSignal=average;

            }
//end blockC

        }


         free(buffer.mData);
         [pool release];
        return noErr;


}

好的: 忽略 blockC 一秒钟。 删除 blockA 和 lineB 解决所有问题。 只删除其中一个 - 泄漏。

我只是无法理解这里的成长。

【问题讨论】:

  • 在 free() 之前检查 buffer.mData 的地址。和 malloc() 返回的地址一样吗?

标签: objective-c c core-audio audiounit


【解决方案1】:

只是一个猜测,但在您的录制回调函数(这是一个超级时间关键函数)中分配一个新的 NSAutoreleasePool 可能是个坏主意。

实际上,你为什么要在这里做这件事?您不应该在 main.m 中为整个应用程序设置一个池吗?这可能会导致您的一些泄漏。

【讨论】:

  • 原因是如果我不把那个线程放在这里,这里就没有自动释放对象的池。我得到错误:“自动释放,没有适当的池 - 只是泄漏”所以我在读到这个后添加了这个:stackoverflow.com/questions/6377730/…
【解决方案2】:

您不应该在音频单元渲染回调中做任何需要内存分配的事情。使用通用 Objective C 的实时性要求太高了。

由于您不应在音频单元回调中分配池或任何其他内存,因此您不应使用任何可能或实际创建任何对象的 Objective C 方法,例如字典修改或通知创建。您可能不得不退回到在渲染回调中使用纯 C(设置标志),并在另一个线程中的渲染回调之外执行您的 Objective C 消息传递(例如,在计时器回调中轮询标志之后)。

【讨论】:

  • 非常感谢,但问题是即使我删除了回调的所有内部并将代码放在上面,由于块A,我仍然有泄漏。这是为什么???
  • 你删除了 malloc() 吗? (或将其移到回调之外?)
  • 不,我没有,应该吗?根据苹果和网上的许多指南,它应该在那里。我有 malloc 和免费的。
  • 虽然出于性能原因这是正确的,但它不会导致内存泄漏,因此不直接回答问题。
猜你喜欢
  • 2017-06-14
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-18
  • 2019-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多