简体   繁体   English

在设备上运行应用程序时出现“收到内存警告”

[英]“Received memory warning” while running app on device

I'm working on an iPhone Video decoder application. 我正在开发iPhone视频解码器应用程序。 I need to convert raw pixel data for each frame and render it on the screen continuously (Hence forming a video). 我需要为每个帧转换原始像素数据,并在屏幕上连续渲染(因此形成视频)。 The function below is the one that renders each frame on the screen. 下面的功能是一种在屏幕上渲染每一帧的功能。

   - (void)drawBufferWidth:(int)width height:(int)height pixels:(unsigned char*)pixels
    {

         CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

         CGContextRef gtx = CGBitmapContextCreate(pixels, width, height, BitsPerComponent, BytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
         CGColorSpaceRelease(colorSpace);   

         myimage = CGBitmapContextCreateImage(gtx); //myimage is of type CGImageRef
         CGContextRelease(gtx);

         img.image = [UIImage imageWithCGImage:myimage]; //img is of type UIImageView
         [CATransaction flush];
         CGImageRelease(myimage);

         myimage = Nil;
    }

The code is working absolutely fine on the simulator. 该代码在模拟器上可以正常工作。 When I run it on the device, it displays few frames, gives "Received memory warning" and crashes. 当我在设备上运行它时,它显示几帧,并显示“接收到内存警告”并崩溃。

I'm not able to figure out where the problem is. 我无法弄清楚问题出在哪里。 Am I not deallocating properly or even though I'm releasing the image, it is still existing in the memory, thus eating up the memory? 我是否没有正确分配内存,或者即使我释放映像,映像仍存在于内存中,从而耗尽了内存?

Kindly help! 请帮助!

Thanks in advance. 提前致谢。

EDIT: 编辑:

The Xcode organizer says the following: Xcode组织者说:

hevcd[665] has active assertions beyond permitted time: 
{(
    <SBProcessAssertion: 0x11aacf70> identifier: Suspending process: hevcd[665] permittedBackgroundDuration: 10.000000 reason: suspend owner pid:565 preventSuspend  preventThrottleDownCPU  preventThrottleDownUI 
)}

A couple of observations: 一些观察:

  1. Let's imagine that you have a for loop: 假设您有一个for循环:

     for (i = start; i < end; i++) { // doing lots of memory intensive stuff } 

    You must recognize that any memory that is auto released during this loop will not actually be yielded back to the operating system until that loop completes and the auto release pool is flushed. 您必须认识到,在该循环过程中自动释放的任何内存实际上都不会退还给操作系统,直到该循环完成并且刷新自动释放池为止。 When doing memory intensive operations, you could theoretically do: 理论上,当执行内存密集型操作时,您可以执行以下操作:

     for (i = start; i < end; i++) { @autorelease { // doing lots of memory intensive stuff } } 

    That way, you're manually creating a new autorelease pool that will be flushed with greater frequency. 这样,您可以手动创建一个新的自动释放池,该池将以更高的频率刷新。

  2. Having said that, you really should not be doing prolonged tasks that do not yield back to the operation system (at least on the main thread, and because you're doing UI stuff, you have to do that on the main thread). 话虽如此,您实际上不应该执行长时间的任务,这些任务不会退回到操作系统上(至少在主线程上,并且因为您正在执行UI事务,所以必须在主线程上执行此操作)。 A better model than performing some prolonged for loop would be let the operating system call your code at some regular interval. 与执行延长for循环相比,更好的模型是让操作系统每隔一定的时间间隔调用代码。 Then the standard autorelease pool will do it's job and you should be fine. 然后,标准的自动释放池就可以完成工作,您应该会很好。 You create a timer like so: 您可以这样创建一个计时器:

     - (void)startTimer { self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES]; } 

    You then have a routine to handle the timer: 然后,您有一个例程来处理计时器:

     - (void)handleTimer:(NSTimer *)timer { // do what you need here } 

    Make sure that you turn off your timer (eg when the view disappears), or else when this view controller is dismissed, it won't be released because the timer will maintain its strong reference to it and you'll have a retain cycle (or strong reference cycle) and you'll leak memory. 确保关闭计时器(例如,当视图消失时),否则关闭该视图控制器时,将不会释放它,因为计时器将保持对它的强烈引用,并且您将拥有一个保留周期(或强大的参考周期),您将泄漏内存。

     - (void)viewWillDisappear:(BOOL)animated { [self.timer invalidate]; } 
  3. You can achieve similar functionality using CADisplayLink , too. 您也可以使用CADisplayLink实现类似的功能。 You can create the display link: 您可以创建显示链接:

     - (void)startDisplayLink { self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)]; [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; } - (void)handleDisplayLink:(CADisplayLink *)displayLink { // do what you need here } 

    and again, you'd want to make sure you stop it when you're done: 再次,您需要确保在完成后将其停止:

     - (void)viewWillDisappear:(BOOL)animated { [self.displayLink invalidate]; } 

All three of those scenarios could probably remedy your memory situation (unless you have some undetected retain cycle or leak). 所有这三种情况都可能会纠正您的内存状况(除非您有一些未检测到的保留周期或泄漏)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当我的设备上运行其他应用程序(2个或更多应用程序)时,ImagePickerController使我的应用程序崩溃,并显示“ Received Memory Warning” - ImagePickerController crashes my app saying “Received Memory Warning” when there are other apps running on my device (2 or more apps) 使用PDF时收到接收到的内存警告时应用程序崩溃 - App Crashed while getting Received Memory Warning while using PDF 应用程式当机,未收到记忆体警告 - App crash, no memory warning received 运行UIWebView时收到内存警告 - Received memory warning when running UIWebView 拼接图像时收到内存警告 - Received Memory Warning while stitching images UICollectionView在滚动时收到内存警告 - UICollectionView received memory warning while scrolling iOS和Cocos2d:收到内存不足警告,只有20 MB的分配并且没有正在运行的其他应用程序 - iOS and Cocos2d: received low memory warning with only 20 MB of allocation and no ther app running 在我的服务器上上传100多张图像时收到内存警告和应用程序崩溃 - Received memory warning and app crash while uploading more than 100 images on my server 如何在应用中捕获崩溃报告警告:收到的内存警告 - How to catch warning in app for Crash reporting: Received Memory Warning IOS应用程序因低内存而被杀死,但未收到内存警告 - IOS app killed for Low Memory but no Memory Warning received
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM