1

Because if Instruments is run and Activities Monitor is chosen, the app running on iPhone 4S is using 4.88MB if the contexts are released, and is also 4.88MB if the contexts are not released. So does that mean releasing context is optional? (I thought it is required actually). The contexts were referenced by CGContextRef variables. (ARC is being used).

The contexts were CGBitmapContext, created for the Retina display, so at about 640 x 640, and there are 4 such contexts, which are all created in viewDidAppear, and I thought if 1 pixel is 4 bytes, then each context will be 1.6MB already. Could it be that after the viewDidAppear is done, the contexts were automatically released? Basically, I generated CGImage objects from those bitmap contexts and set the CGImage objects to be pointed to by the CALayer objects (using layer.contents = (__bridge id) cgImage;), so the bitmap contexts were no longer required. It is compiled using Xcode 4.3, with ARC, and targeted towards iOS 4.3. (but I thought CGContextRef is not part of ARC).

update: correction: it should be "generate CGImage objects from those CGBitmapContext, and set those CGImage objects to CALayer" (the original question is edited to reflect that).

nonopolarity
  • 146,324
  • 131
  • 460
  • 740

1 Answers1

5

Releasing a CGContextRef is not optional, but you should be aware of whether or not you need to release it. It follows the standard manual memory management rules. If you take ownership (alloc, create, retain, and a few others) you must release ownership (release). If you release when you don't have ownership, it's an overrelease.

What you're probably seeing is that even after you've released the object, someone else is retaining it. It's probably something in your view hierarchy. An object not releasing after you release your ownership is typically not a problem.

wjl
  • 7,143
  • 1
  • 30
  • 49
  • if one such context can be 1.6MB, then 4 of them should be 6.4MB, so how come the app is running using only 4.88MB of RAM? Also, the bitmaps were created using those contexts, and set to CALayers, and the bitmaps were also released, but I think the CALayer is taking ownership (I am surprised it doesn't crash... because releasing the bitmap like that can make the CALayer point to released bitmaps?) But if each bitmap is also 1.6MB, then there are 8 of these 640 x 640 items... so should be 12.8MB usage... – nonopolarity Aug 17 '12 at 19:11
  • If the CALayer takes ownership, the bitmaps will persist even when you release them. Calling release says "I'm done with this", but it won't be thrown away until everyone has released it. – wjl Aug 17 '12 at 19:17
  • even the Core Graphics items have reference counts? I thought only real objects have reference count? – nonopolarity Aug 17 '12 at 19:20
  • Yep! CGContextRef is actually a real object. The relation between CF and Objective-C objects is a really interesting one. But yes; you almost always need to use retain and release (except when using ARC with Objective-C objects). – wjl Aug 17 '12 at 19:25
  • (by CGBitmap I actually meant CGImage). so with ARC... do we still need to release those CGImage and CGContext, or, will we need to specifically release them because ARC doesn't take care of them? (only take care of other objects). When I was reading the book Programming iOS by Matt Neuburg, I thought I saw him releasing those CGContext and CGImage even thought he would use ARC. – nonopolarity Aug 17 '12 at 19:38
  • 3
    @動靜能量 - ARC does not manage CF types, so you still have to balance retains and releases for those. – Brad Larson Aug 17 '12 at 19:39
  • thanks. and I suppose CGContext and CGImage are handled by the same reference count mechanism, and we need to do manual retain/release even with ARC enabled, and they can't be used with the autorelease pool? – nonopolarity Aug 17 '12 at 19:48
  • The reason you don't have big leaks is that the context is not the object retaining the data - its the CGImageRef. The context is quite small compared to the image backing data. – David H Aug 17 '12 at 20:05
  • interesting, so CGBitmapContext by itself has all the image's info, but once the CGImage is obtained, the image's data itself is also in CGImage, and therefore CGBitContext dangling there doesn't waste much memory? – nonopolarity Aug 17 '12 at 20:45
  • Also, it depends on where you are looking. If you are just looking at Live Bytes it doesn't tell the whole story at all. You need to go into the VM Tracker section of Instruments and check out your "dirty memory" usage. Memory that is used internally (i.e. can't be freed for the system) by your application is shown here. This definitely includes pixel data for images, etc. I bet you will look at that and see a higher number than 4 MB. – borrrden Aug 18 '12 at 02:04