6

I'm working on a kiosk style slideshow app. I have a UIScrollView which shows the slides, and a factory class, which generates the slides. The "slides" themselves are UIViewController subclasses, which are loaded out from XIB files and customized by the factory class. In my main view controller, I set up the scroll view and start a timer. The timer calls a "reload" method every N seconds, which handles the reload and call to the factory class.

The method that the factory class uses looks something like this:

- (SlideViewController *)slideFromManagedObject:(Slide *)managedObject{

  NSInteger slideType = [managedObject slideType];

  switch(slideType){
     case kSlideTypeA:

  { 
       //
       //  configure arguments here
       //

       return [[SlideViewController alloc] initWithArgument:argument] autorelease];
         break;

  }

    //
    //  More types here...
    //

    default:
      break;
  }


}

I haven't yet gotten to the point of defining all of my cases, but the ones that are filled out seem to cause jumps in memory usage. If I add return [[[UIViewController alloc] init] autorelease]; right before the switch/case, I get no visible view, as expected, but I also don't see those memory increases. I'm not sure, but I suspect that it's the "C blocks" that I'm wrapping my slide generation code in.

Some things to note:

  • When the app starts, I see the memory plateau from about 400 kilobytes to around double that. Then, when the slides progress, any of the slides whose generation code is contained in curly braces is called, the memory plateaus upwards again.

  • This behavior only seems to happen once per launch - when the app loops through all of the slides, the plateaus to_not_ happen again. However if the app is backgrounded and then relaunched, the plateaus do occur again, consuming even more memory.

  • When I left the app to run overnight, for about 10 hours and forty minutes, the memory usage had slowly climbed from about 1.44 megabytes to somewhere closer to 1.57 megabytes. I suspect that there are/were some other leaks in there that may have been fixed by my tweaking, but the main jump from about 800 kilobytes to somewhere between 1.4 and 1.5 megabytes is still an issue.

Instruments does not report any leaks, but the plateauing concerns me.

What could be causing the increased memory?

EDIT:

So I don't think it's the blocks, since using an if/else seems to do the same thing. Here's a screenshot of the Allocations instrument running:

enter image description here

Where could possibly be holding on to these views?

Community
  • 1
  • 1
Moshe
  • 57,511
  • 78
  • 272
  • 425
  • Maybe your holding on to the memory even though you'r not using it? What do you find if you do "heap shots" in Instuments? (That will find all memory that has been allocated between given points, not just during the entire lifetime of your application.) If you do many regular heapshots, say one for every new SlideViewController or one between every relaunch as you mention increases the memory, then you should be pointed to what data is being "leaked". Without that information it's really hard to tell what the problem is – David Rönnqvist Aug 01 '11 at 19:35
  • My guess is that the old slides are not being dismissed or popped off the view stack and the new views are being presented on top. This will leave the old view in memory (not a leak). Perhaps you can show the code where you present the new view loaded from the xib? what are you doing in the `willDisappear` methods of your custom view controllers? – falconcreek Aug 01 '11 at 19:45
  • @falconcreek - The memory does not gradually increase, just once per slide per "curly block" per launch. – Moshe Aug 01 '11 at 20:08
  • @DavidRönnqvist - What data should I add to the question to clarify? – Moshe Aug 01 '11 at 20:15
  • each new slide is added to the heap (new plateau). the old slides are still on the heap as they are not being dismissed. – falconcreek Aug 01 '11 at 20:36
  • @falconcreek - Only some of the slides are causing a new plateau. (The ones in curly braces. The default slide for the not-yet-implemented cases do not.) – Moshe Aug 01 '11 at 20:40
  • your code doesn't show the "default slide" being created or presented. the default slide will not increase the memory in use if you are not calling `alloc` `init` – falconcreek Aug 01 '11 at 20:50
  • @falconcreek - whoops. Let me add that. – Moshe Aug 01 '11 at 20:52
  • @falconcreek If you don't mind, perhaps we can [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2035/discussion-between-moshe-and-falconcreek) – Moshe Aug 01 '11 at 20:52
  • @RobertHarvey - This is not a dupe! – Moshe Aug 09 '11 at 20:50
  • You say "If I add return [[[UIViewController alloc] init] autorelease]; right before the switch/case, I get no visible view, as expected, but I also don't see those memory increases." But a visible view consumes much more storage than an invisible one. Image buffers consume a lot of storage. – Hot Licks Aug 09 '11 at 21:39
  • @DanielRHicks, right, but is that what's causing the odd memory pattern? Could there be a way to force the image cache to release? – Moshe Aug 09 '11 at 21:56

1 Answers1

2

One possible explanation for what you are seeing is some caching that UIKit (I assume) is doing of your objects (don't know what they are, but I think of images mostly).

Caching is often used during transitions and for other internalities of UIKit.

UIKit empties its caches usually when a memory warning is received, so you could try and send one to see what happens. In actuality, I suspect that results of sending a memory warning will not be very easy to analyze, since all of your views are also unloaded, hence memory will go down forcibly. But you can try...

As to how sending a memory warning to the device (as opposed to the simulator), here you find an useful S.O. post.

Community
  • 1
  • 1
sergio
  • 68,819
  • 11
  • 102
  • 123
  • Turns out that this is likely what's causing my problem. I'm doing an animation at regular intervals, so this could be it. I've also noticed my cache be cleared every now and then, and the memory usage drops. – Moshe Sep 04 '11 at 22:56