如何释放 ARC 中的内存以进行高内存使用图形渲染?

发布于 2025-01-01 12:08:18 字数 412 浏览 1 评论 0原文

首先,感谢这个网站上的每个人...它对于深入了解 iOS 编程非常有帮助。

我当前的问题:

我有一个应用程序可以渲染非常风格化的照片版本。它使用一些 CoreImage 过滤器来处理其中的一些内容,但需要一堆 CoreGraphics 来完成繁重的图像处理。

代理大小渲染效果很好,但是当我渲染图像的全分辨率版本时,它有时会因为内存使用率过高而崩溃。问题是渲染时我需要能够在内存中拥有多个全分辨率(3264x2448)缓冲区。我不知道什么或如何释放更多内存。我一直非常小心地尽可能地匹配 CGImageRelease。

对于 ARC,我如何知道某些内容是否真的已发布并释放?将对象设置为 nil 并不会真正执行任何操作。

我怀疑我是否可以以任何方式将其流式传输到磁盘。

任何建议将不胜感激!

谢谢!

First off, thank you to everyone on this site...it's been INCREDIBLY helpful in getting into the grit of iOS programming.

My current issue:

I have an app that renders a very stylized version of a photo. It uses some CoreImage filters for some of it, but needs a bunch of CoreGraphics to get the heavy image processing done.

The proxy size renders work out great, but when I render a full resolution version of my image, it sometimes crashes because of high memory usage. The problem is that I need to be able to have several full resolution (3264x2448) buffers in memory when rendering. I don't know what or how to free up more memory. I've been very careful with matching CGImageRelease's everywhere I can.

And with ARC, how do I know if something's really been released and freed up? Setting an object to nil doesn't really do anything.

And I doubt I can stream this to disk in any way.

ANY suggestions would be extremely appreciated!

THANKS!

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

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

发布评论

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

评论(3

甜味超标? 2025-01-08 12:08:18

ARC 在这种情况下并没有什么区别。

这只是意味着您不必自己调用 release

对于非 ARC,在内存不足的情况下,您可能想要释放一些您并不真正需要的属性(这意味着它们可以根据需要重新创建)。

- ( void )didReceiveMemoryWarning:
{
    [ _myProperty release ];

    _myProperty = nil;

    [ super didReceiveMemoryWarning ];
}

在 ARC 下,它是完全相同的,只是您不必调用 release

- ( void )didReceiveMemoryWarning:
{
    _myProperty = nil;

    [ super didReceiveMemoryWarning ];
}

将属性设置为 nil 将在 ARC 下自动释放它。
所以它确实做了一些事情。

如果它对您不起作用,那么您肯定遇到了另一个问题。
确保没有内存泄漏,也没有保留周期。

最后一个肯定是有问题的...

ARC doesn't make a difference in such a context.

It just mean you don't have to call release by yourself.

With non-ARC, under low-memory conditions, you may want to release some properties, that you don't really need (meaning they can be re-created on demand).

- ( void )didReceiveMemoryWarning:
{
    [ _myProperty release ];

    _myProperty = nil;

    [ super didReceiveMemoryWarning ];
}

Under ARC, it's exactly the same, except you don't have to call release:

- ( void )didReceiveMemoryWarning:
{
    _myProperty = nil;

    [ super didReceiveMemoryWarning ];
}

Setting your property to nil will, under ARC, automatically release it.
So it really does something.

If it's doesn't work for you, then you definitively have another problem.
Make sure you don't have memory leaks, nor retain cycles.

The last one is certainly the problem...

煮酒 2025-01-08 12:08:18

正如所建议的(但没有明确说明)——这不是 ARC 问题。

您将需要 30 MB 内存来在内存中保存该分辨率的单个图像(3264x2448,假设每像素 32 位)。虽然你没有说内存中需要多少个该大小的缓冲区,但听起来至少是三个 - 对于许多 iOS 设备来说,你基本上已经达到了内存限制(最初的 iPad 和 iPhone 3GS 只有 256MB < em>总共。您可能只能访问第三个。您的应用程序可用的内存变化很大)。

ARC 与垃圾收集不同 - 它只是在编译时添加了release 和retain 语句。如果您的代码结构正确,您的图像将在不再需要时释放。我强烈怀疑如果您关闭 ARC(您可以使用编译器标志逐个文件地执行此操作)您会看到相同的结果。

正如有人已经发布的那样,解决此问题的方法是平铺图像,并一次处理一个小样本。如果您的模糊算法无法解决这个问题,那么残酷的事实是您可能必须编写一个可以解决这个问题的算法!

So as has been suggested (but not explicitly stated) - this isn't an ARC problem.

You're going to need 30 MB of memory to hold a single image in memory of that resolution (3264x2448, assuming 32 bits per pixel). And whilst you don't say how many buffers of that size you need in memory, it sounds like it's at least three - you're basically at your memory limit there for many iOS devices (the original iPad and iPhone 3GS only have 256MB total. Of that, you may only have access to a third. The memory available to your app is highly variable).

ARC isn't like garbage collection - it just adds the release and retain statements in at compilation. If you've structured your code correctly, your images will release when they're no longer needed. I strongly suspect that if you turned ARC off (which you can do on a file by file basis, using a compiler flag) you'd see the same results.

As someone has already posted, the way around this is to tile your image, and work on a small sample at a time. If your blur algorithm can't cope with that then the hard truth is you're probably going to have to write one that does!

过度放纵 2025-01-08 12:08:18

您应该平铺图像并且一次只处理其中的一部分。您可以通过创建 CIImage 然后调用:

[myContext drawImage:myImage atPoint:P fromRect:tileBounds];

循环并更改 PtileBounds 来实现此目的,以便最终覆盖整个输出图像区域。

You should tile your image and only work on parts of it at a time. You can do this by creating your CIImage and then calling:

[myContext drawImage:myImage atPoint:P fromRect:tileBounds];

in a loop and changing P and tileBounds so that eventually it covers the entire output image area.

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