Archive for August, 2006

perl Out of memory! (with solution)

On occassion, I will run a perl script and be shocked when I get an “Out of memory!” error back from perl. The shock is always a result of the fact that I’m doing something relatively benign, running a small script that generates some data but certainly not enough to overrun the massive capabilities of the box I’m running the script on.

It happened to me again today, and I thought I’d put a little post here about it to perhaps save somebody some frustration.

Today’s perl Out of memory error happened while I was upgrading SpamAssassin on the Red Mercury mail server. You wouldn’t think that something as simple as upgrading a few perl modules would be enough to run out of memory, particularly since this machine had nothing else running on it at the time, and the machine has a gig or so of RAM backed by a couple gigs of swap space.

The answer, in my case anyway, always turns out to be “ulimit”. What is “ulimit”? If you live inside a unix world, you probably know all about ulimit. For mere mortals like myself, it’s something that I only care about when it prevents me from doing what I need to do.

“ulimit” is short for “user limit” - it limits the amount of resources that a particular user can consume. This is of course very useful as it prevents any particular user from hogging all of the memory or CPU time on a system. If you run a process from the command line that goes absolutely crazy, ulimit can be the sanity check that keeps the rest of the box humming along nicely.

“ulimit” is usually a built-in shell command, so it varies from shell to shell. I happen to be using zshell on an OpenBSD box, but even if what I describe here doesn’t match exactly what you have on your machine, it should get you headed in the right direction (in fact, just saying “ulimit” may be enough to get you headed in the right direction). It could be that the stock ulimit settings on OpenBSD are smaller than on other default installs, but when I first had this problem, I saw a LOT of people asking this question.
So first, I type “ulimit” to see what’s up:

[ultrabox]: ulimit
unlimited

Ok no problem, right? But as it turns out, with no command line arguments, my ulimit will default to showing me my limit on file size, and that is unlimited. Let’s find out what all of the limits are:

[ultrabox]: ulimit -a
cpu time (seconds) ulimited
file size (blocks) unlimited
data seg size (kbytes) 65536
stack size (kbytes) 4096
resident set size (kbytes) 1446704
…(and some others)…

Now we’re seeing some interesting things. The stack size is 4MB. That might be small. The “resident set size” is set to almost the size of the RAM in the machine (well over a gigabyte) and it is maxed out and can’t go any higher. The “data seg size” is 64MB (65536 kbytes above) - that should be enough for anything, right?

It has been my experience that, when working with perl, a 64MB data seg size is too small. I have to make it larger before running most of my reasonably-complex data processing scripts. And, today, I had to make it larger before doing something simple like upgrading SpamAssassin via CPAN. Even though I ran the upgrade with “sudo”, I still had to raise the data seg size ulimit in my shell, since it was limiting the data seg size for everything run from that shell.

So, Greg Graffin, I HAVE THE ANSWER!!!

Simply boost the size of your data seg and make that stupid perl Out of Memory! error go away:

[ultrabox]: ulimit -d 200000

[ultrabox]: perl irsProcessAllUSTaxReturns.pl

Processing… 130,728,360 tax returns… Finished!
[ultrabox]:

It worked!

For scripts that I run often, or from a cron job, I make a little shell script that first sets the “ulimit -d 200000″ and then runs the script. Other possibilities would be to set the needed ulimit settings in a login script, or to bump up the default system-wide (though the method for doing this system-wide varies by system and you might not have the required permissions to do it anyway).

Please note the number of zeros there in the ulimit setting - five zeros - this sets the ulimit to close to 200MB up from the 64MB it was set at previously. You may need more. You may need less! On the less side it doesn’t matter so much - this is just a top limit, it doesn’t mean everything will use 200MB of data segment space, it just allows things to use that much space.

Now, as for the bigger question of WHY perl needs over 64MB of data segment space to do something like install spamassassin… well, in the words of a Gary Sommer, guy I used to work with, “that’s beyond my attention span.”

City Lights

City Lights, a 1931 Charlie Chaplin silent film, is pretty boring. Some of the visual and slapstick gags are amusing, but they are drawn out way past the funny point. By this point in Chaplain’s career, he was focusing more on character development, and though you get to know the various characters fairly well, their interactions are simplistic, and the ending falls flat.

I don’t like my opinion of City Lights. Part of me says I should cut the movie some slack, because it’s a silent film. Or maybe I should look at in context, with the other films of that era, and judge it against those works. It could be that I’m just ruined by modern attention-grabbing techniques and am incapable of slowing down to appreciate a fine work from a simpler era. Maybe I’m getting old, and my mind is closing.

Or maybe I’m just more honest with myself these days.

This film is a cautionary lesson in technological progress. It was made in 1931, four years after the technology for movies with audio tracks (”talkies”) became available. While watching City Lights, it is painfully obvious that sound is missing (there is, of course, a musical score that punctuates some of the events in the film, but watching the actors’ lips move with no accompanying voice is creepy). When the original silent films were made, it was simply a technological issue. It wasn’t feasible to record and play back the audio in sync with the film, so the filmmakers did the best they could, and made silent films. They didn’t let the lack of sound stop them.

But Chaplin made a lot of silent films. So many, in fact, that he stopped seeing the lack of sound as a problem, and started seeing it as a necessity. Once the technological limitation was lifted, he could not embrace it, and instead saw it as a threat to his way of working, and as a threat to every film he had ever made.

This is a problem that we all face throughout our lives. When we’re young and haven’t yet learned the limits of ourselves or the world around us, we look at things and wonder why they aren’t the way we would like them to be. As we get older, we run in to those limits, and we learn that things are the way they are for a reason. We accept those limitations, and we adapt to them. We may make great advances by pushing hard against these limitations.

Then one day, we wake up, and those limitations are gone. Every great push against those limitations now looks ridiculous. Where there once was a brick wall, there is now a wide open field that stretches for as far as the eye can see. We look down at the patch of ground where we once were proud to have struggled to move that brick wall an inch, and see that someone else has effortlessly moved the wall hundreds of miles while we were resting. Our once-acclaimed lifelong achievements have been reduced to a silly, historical curiosity.

When this happens, when the brick wall disappears, we look to the horizon and we see these innovators disappearing into the mist, charging ahead into lands that to us were once a dream, but that we now consider to be forbidden. Those charging ahead look to us like trespassers, and we try to convince ourselves that they are foolish, that they will fall off the edge of the flat earth, leaving us to move ahead inch by inch again as we have always done.

Soon, however, the reports come back that these adventurers who have removed our wall are continuing to make progress, and are in fact accelerating, and we think back to our younger years and realize that these innovators are living our dream. We look down again at our life’s work in anguish. What is the point of taking another step? One step would take us farther than we ever imagined, but as the rest of the world accelerates thousands of miles away from us, we relegate ourselves to being washed up, retired, finished.

Of course, these days, changes like this happen all the time. They happen quickly, but it takes us all a while to see their importance. By the time we look to the horizon, it feels like we have been left behind. Fortunately, the new horizon is never as far away as it looks. Once we take that first step, we find ourselves on the tail of those innovators, and with our experience and insight, we find that keeping pace and pulling ahead again is really not so hard. Soon we look back over our shoulders and see many others standing where that wall used to be, looking to us, and cheering us on.

And the moment we step past that wall and start charging toward the horizon, it’s fun all over again.