On a whim, I took a shallow dive into the world of C this weekend. Its been a long time since I delved into C. I ended up spending nearly as much time tweaking a build script with the ever-amusing Rake as I did remembering my C skillz[1]. In the end, my goal was to write a simple program that just reads a file and writes it back out. Nothing cat
couldn’t handle, sure, but you gotta start somewhere.
Of course, the first thing you’ll notice when you go from Ruby on Friday to C on Saturday is that OMG I have to write fourteen-billion lines of code just to open a file? Well, yeah, you do. But the language isn’t that awful. Munging file pointers, getting buffer sizes by stat
ing a filename and all that, it’s kinda fun.
What’s not fun? Managing memory. It’d be fun if it wasn’t just an express ticket on the memory leak train. So lots of people have tried to tackle this. I was playing with the Apache Portable Runtime or APR, in concert with all this C and they take an interesting tack in dealing with memory.
Jumping in the memory pool
In the APR world, your application creates one or more pools that you then allocate memory from. You create a “root” memory pool to start off with, but you can create as many further pools as you like.
The idea is that as you transition from one area of functionality to another, you create a new pool. Once you’re done with that function, you destroy the pool and all the memory allocated to it goes away. Including the stuff you forgot about. Which is kinda rad, it being the case that memory leaks are leaks of (human) memory.
This made me think of generational garbage collection. Java’s garbage collector does this clever trick where objects are initially created in a “nursery” with all the other recently created objects. Since it’s typical that objects are created and then quickly discarded, the nursery is basically the low-hanging fruit for the garbage collector to find memory when it needs to.
Bring that funk back over here
Seems to me you could do the same thing with the APR’s pools. Create a new memory pool for every request, for example. Then when you’re done with the request, just delete the pool and don’t worry. The APR folks list examples of assigning pools to starting your application, parsing the configuration and then doing your actual processing. That sounds reasonable to me too.
This is probably not rocket science. In fact, the developers of the APR readily acknowledge that tuning your app to work with this approach to memory management is the trickiest and most contentious[2] facet of developing with the APR. In the next release, they’re working on an alternative, just in case pools aren’t your thing.
Nonetheless, I find it pleasing that the world of C seems to have, perhaps, moved on from “man up and manage your own memory, we are C programmers!” to “hey man, everyone has trouble with this stuff, give this approach a try!” At some point, with some problems, C becomes a necessity. Anything that helps that out is moving the bar higher for the practice of programming.
[1] Indeed, my build yaks are beautifully shorn
[2] Perhaps you could say, opinionated