The kernel killed my process (in the Library, with a lead pipe)

Greetings, and hoping this is the right forum.


I had something shocking happen today. I was running a process that rebuilds a 2TB database. About 5 hours into the process, it simply stopped. There was no crash report nor anything in the program's log output that would indicate a problem; the output just ended.


I eventually dug through the system.log and found the culprit:


Jul  7 16:02:14 madhatter kernel[0]: low swap: killing pid 4022 (QRecallHelper)


OMG!


So the kernel decided it was running low on memory and arbitrarily decided to kill my process???? I can't express how dismayed I am about this. How am I supposed to ship a program to customers that the kernel might decide to kill at any point, just because it's doing too much work? (Not to mention that I just lost 6 hours of rebuild work and now have to start over.)


I know my process is memory hungry, and can eat up as much as 6GB of RAM. But my system has 20GB of physical RAM and over 200GB of free disk space on the system volume, so I was in no danger of running out of addressable memory. Furthermore, the program is written so it scales its memory use so as not to exceed the physical RAM installed in the system (although it's VM foot print can often be larger due to memory mapped files and such).


Is there anyway of preventing this from happening? Is there some BSD function I can call that says "This process uses a lot of RAM, please don't kill it!!!!"

Replies

There's an OS X feature called Automatic Termination that automatically terminates processes that are no longer being used if memory gets too tight. Have a look at your Info.plist and see if you see anything marked 'NSSupportsAutomaticTermination.' If not, try adding it to your plist, with a value of NO. That will completely disable Automatic Termination for your app, but that will work for you only if that's why your app was getting terminated. It may be something else deeper in the OS, however, so if disabling Automatic Termination doesn't solve your problem, I'm afraid I won't be able to help you any further.

Thanks bob133, but I don't think that's it. The Automatic Termination applies, as far as I can tell, only to Cocoa apps, and only to Cocoa apps that have enabled the feature. My process is a background helper started by launchd.

I strongly suspect you're wrong about the maximum amount of memory your process uses, presumably because it has a bug. It doesn't make any sense to be able to mark a process as "don't kill" because the kernel is already only doing it as a last resort. (And besides, surely everybody would mark all of their processes as such, because everybody assumes their process is the most important ever.) All OSes will do something similar because the only alternative is to panic the whole system in the face of a runaway process.


You can try reproducing the problem but have some automated monitoring and logging going on to try to catch the problem shortly before the kernel kills your job. For example, run the "top -l 1 -o vprvt", vm_stat, and "vmmap -v <pid>" commands every second or so, keeping the last several, until your process is killed.

FYI, it's easier to just attach to it with Instruments and use that to monitor its allocations on an ongoing basis. It also provides a lot more info if you find that it really is suddenly pigging out on memory.

dgatwood,


I eventually figured out what was going on.


My process was started from a helper, that was started from an app, that was run in Xcode. What was happening is that Xcode had Zombies enabled, which the helper, and eventually the command process, managed to inherit via the environment. So my command process (which reads and writes millions of files) never deallocated anything!!!!


I guess I should be lucky that I didn't find a molten crater on my desk where my MacPro originaly was.

Yeah, accidentally leaving Zombies enabled would do that. I've done it before too. 🙂 Glad to hear you were able to solve your problem.