Posts Tagged ‘garbage collection’

Interior Pointers For The Lose

Friday, December 19th, 2008

Remember the post I made awhile back, talking about how I needed to turn off optimizations for two pieces of code and I didn’t understand why? Of course you do, it was here, remember? Well, I was listening to the latest episode of Late Night Cocoa wherein they were talking about garbage collection. The guest, Andre Pang, made a comment about how crashes with code that uses C pointers into NSData objects were fairly common. Ding ding ding!

See, the problem is this. I have code this like at the top of my problem functions:

NSData* theData = [some data blob];
byte* myPointer = [theData bytes];

The problem here is that I then use “myPointer” for the remainder of the function as I read from the data blob. As far as the runtime is concerned, I’m done with “theData” since I never talk about it again throughout the entire function. It doesn’t care about my C pointer, it only sees that I’m no longer talking about “theData“. So it marks it as collectable and the GC comes along at some random point and removes my data from underneath my feet.

The solution is to add a line of code to the end of the function that looks like this:

[theData self];

This is a do-nothing line of code but it DOES force the runtime not to mark the object as collectable since it’s going to be talked about again at the end of the function. This fixes my random crashes! I was able to remove the stupid pragma statements and now everything hums along as it should.

Amazing what you can learn from a humble podcast! Thanks, Late Night Cocoa!

Garbage Collection Redux

Sunday, June 8th, 2008

OK, so I’m back to NSAllocateCollectable as my weapon of choice instead of using NSMutableData objects. I was getting weird errors with NSMutableData here and there so I thought, well, why not see what was actually wrong with my NSAllocateCollectable implementation?

The problem I was having that loading a large map would completely blow out my 2 GB of RAM and stall the machine. That didn’t seem right for a Quake map. So I looked into it and the problem was two things.

First, the garbage collector wasn’t getting any time to run during the map load sequence. So while I’m creating verts and brushes and planes like crazy the GC is sitting there patiently waiting for a processor break to do it’s job – which doesn’t come until the end. So I stuck in some strategic calls to [[NSGarbageCollector defaultCollector] collectIfNeeded] and that’s happy now. Map loading only allocates a few hundred MB in total.

Secondly, my render array implementation was doing a lot more work than it needed to. What I wrote for speeding up rendering was an array of vertices, uv coordinates and colors represented by a blob of float data in RAM. It allocates a new blob within the greater blog for each new vert/uv/color that the editor wants to draw (these are grouped by texture, so all of the verts that use the same texture are drawn as one OpenGL call). It tried to optimize performance by keeping a chunk allocated that represented the maximum number of verts that were ever requested for that particular texture. This meant that it could save itself from allocating the data blob every frame for every texture. The trouble was that when it came time to resize the array to accommodate more verts, it wouldn’t allocate very much so it was constantly resizing the array during a map load. This ate time like crazy. Once I changed my “grow array by” value to something much larger, it took maybe 45% off of the load time for large maps. It wastes a little more RAM now but since we’re talking about a few hundred MB at the most here, I’m not concerned.

So I’m fully garbage collected now. Hooray!