无法修复 Open AL 造成的严重内存泄漏

发布于 2024-08-07 18:54:28 字数 961 浏览 2 评论 0原文

我的一个大型 iPhone 项目即将结束,在检查内存泄漏时偶然发现了这个巨大的项目。我按照本教程实现了声音:

http://www.gehacktes.net/2009/03/iphone-programming-part-6-multiple-sounds-with-openal/

很有魅力,很多人使用它,但我得到了巨大的当声音最初加载时,泄漏是项目的开始。下面是泄漏开始的代码行:

[[Audio sharedMyOpenAL] loadSoundWithKey:@"music" File:@"Music" Ext:@"wav" Loop:true];
[[Audio sharedMyOpenAL] loadSoundWithKey:@"btnPress" File:@"BtnPress" Ext:@"wav" Loop:false];
[[Audio sharedMyOpenAL] loadSoundWithKey:@"ting1" File:@"GlassTing1" Ext:@"wav" Loop:false];

等等。它总共加载了 20 个声音。更具体地说,在 Audio.m 文件中这段代码:

+ (Audio*)sharedMyOpenAL {

@synchronized(self) {
    if (sharedMyOpenAL == nil) {
        sharedMyOpenAL = [[self alloc] init]; // assignment not done here

    }
}
return sharedMyOpenAL;
}

我不确定如何解决这个问题,对于此事的任何帮助将不胜感激。

谢谢。

I'm nearing the end of a big iPhone project and whilst checking for memory leaks stumbled on this huge one. I implemented the sound following this tutorial:

http://www.gehacktes.net/2009/03/iphone-programming-part-6-multiple-sounds-with-openal/

Works a charm, a lot of people use it but I get a huge leak a start of the project when sound is initially loaded in. Below are the lines of code that start of the leak:

[[Audio sharedMyOpenAL] loadSoundWithKey:@"music" File:@"Music" Ext:@"wav" Loop:true];
[[Audio sharedMyOpenAL] loadSoundWithKey:@"btnPress" File:@"BtnPress" Ext:@"wav" Loop:false];
[[Audio sharedMyOpenAL] loadSoundWithKey:@"ting1" File:@"GlassTing1" Ext:@"wav" Loop:false];

etc. etc. it loads in 20 sounds altogether. And more specifically in the Audio.m file this chunk of code:

+ (Audio*)sharedMyOpenAL {

@synchronized(self) {
    if (sharedMyOpenAL == nil) {
        sharedMyOpenAL = [[self alloc] init]; // assignment not done here

    }
}
return sharedMyOpenAL;
}

I am unsure how to resolve this and any help on the matter would be greatly appreciated.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

羁客 2024-08-14 18:54:28

“泄漏”不就是 Audio 单例吗?我不确定泄漏检测是如何工作的,但从某种角度来看,大多数单例都是泄漏,因为它们仅在应用程序退出后释放内存。

如果确实如此,那么就取决于您是否需要释放声音所使用的内存。内存使用量不应增加,因此您不必担心“传统泄漏”场景,即您的应用程序占用越来越多的内存直到被杀死。您使用的代码似乎不支持声音卸载,因此如果您想释放内存,您必须自己添加该代码。

还有个人观点:使用单例编写音效引擎并不是一个好的设计。管理声音变得很痛苦(这正是你面临的问题),单例添加了很多不必要的样板代码等。我认为没有理由声音不应该是具有自己生命周期的简单独立对象 - 这就是方式我已经在我对 OpenAL SFX 引擎的尝试中完成了这项工作。当然,我也可能是错的。


更新:我认为神奇的“此处未完成作业”是关键。单例代码取自 Apple 文档,但有人插入了额外的作业。 sharedFoo 方法应如下所示:

+ (MyGizmoClass*)sharedManager
{
    @synchronized(self) {
        if (sharedGizmoManager == nil) {
            [[self alloc] init]; // assignment not done here
        }
    }
    return sharedGizmoManager;
}

当您对 self 执行额外赋值时,您就创建了您要查找的泄漏。

Isn’t the “leak” simply the Audio singleton? I am not sure how the leak detection works, but from a certain viewpoint most singletons are leaks, since they only release memory after your application exits.

If this really is the case, then it depends on whether you need to release the memory used by the sounds. The memory usage should not go up, so you don’t have to worry about the “traditional leak” scenario where your application takes more and more memory until it gets killed. The code you are using does not seem to support sound unloading, so that if you want to release the memory, you’ll have to add that code yourself.

And a personal viewpoint: Writing a sound effect engine using a singleton is not a good design. Managing the sounds becomes a pain (this is exactly the problem you are facing), the singleton adds a lot of unnecessary boilerplate code, etc. I see no reason the sounds should not be simple separate objects with their own lifecycle – this is the way I’ve done it in my attempt at an OpenAL SFX engine. Of course, I could be wrong.


Update: I suppose the magic ‘assignment not done here’ is the key. The singleton code is taken from the Apple documentation, but somebody inserted an extra assignment. The sharedFoo method should look like this:

+ (MyGizmoClass*)sharedManager
{
    @synchronized(self) {
        if (sharedGizmoManager == nil) {
            [[self alloc] init]; // assignment not done here
        }
    }
    return sharedGizmoManager;
}

When you perform the extra assignment to self, you create the leak you are looking for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文