Monday, November 13, 2017

App Nap, Automatic Termination, and Zombie Apps

Howard Oakley:

More recently, Apple’s apps have started to behave differently. Support tools like TextEdit and Preview enter this [zombie state] instead of quitting automatically, when they go into App Nap without an open document. You can observe this by starting them up and leaving then to go into the background without any open documents.

With a longer list of apps open and in the background, most of them now go into App Nap, as shown in Activity Monitor.

Bring up the Force Quit dialog using Command-Option-Escape, and you’ll see that they are still listed there as running.

Look at their icons in the Dock, though, and the normal black dot has vanished, as if the app has actually quit.

They’re also missing from the list of open apps in the App Switcher (Command-Tab).

[…]

macOS has therefore gone from having two basic states for apps, to four[…]

Howard Oakley:

To prevent all apps from becoming zombies, simply type the following into Terminal:

defaults write -g NSDisableAutomaticTermination -bool TRUE

When you next open an app like Preview, if you leave it unattended in the background with no open windows, it will just sit there, and won’t quit or become a zombie.

Howard Oakley:

This zombie state is possibly the most complete antithesis of all good human design. The app is still there, but the user can’t directly use or quit it. The only two ways of regaining control over it are to open a document which by default will be opened by that app, or to act as if opening the app again. As zombies are removed from the Dock, App Switcher, etc., the latter is often very inconvenient.

[…]

This sort of behaviour is probably most tolerable when it occurs in such one-shot viewer utilities. But when it becomes standard in major productivity apps like Pages, Numbers, and Xcode, you have to ask why macOS is being so deliberately deceptive of the user. As Apple glosses over the matter in a couple of terse lines, and then only in its developer documentation, we’ll never know its design intent.

Update (2017-11-15): Howard Oakley:

In the absence of anything better, I suggest that they are termed undead apps, which has no other meaning in this context, and should therefore be unambiguous. It also seems a good description as to what they are. And despite my previous assertion, it appears that they can only exist for any length of time in App Nap. Indeed, as I show here, all apps running under macOS Sierra and High Sierra are eligible for App Nap, irrespective of custom settings in their Info.plist file.

10 Comments RSS · Twitter

I think it's clear that Apple think the iOS model of apps you never should have to care whether they are open or not is superior, and would like Mac apps to behave the same.

I think Apple is right here. While most of tech reader understand the different applications states, many users don't understand that when all documents are closed, the app remains active and continue to eat up RAM and resources.
I just would like that much more apps (especially built-in apps) support Automatic Termination.

@Jean-Daniel Well, but zombie apps in a way make that worse because the system shows the app as not running when it actually is using resources.

@Michael: You can always date old pre-OS X Macsters by the depth of their neurotic obsession with real/imaginary RAM/disk pressure. Hell, they probably still try to reinstall Connectix RAM Doubler after every system update!

I'm going to presume a zombie app uses only RAM, not CPU, so won't slow other processes while dormant and can be automatically terminated by the OS any time that RAM becomes needed elsewhere. Simple caching mechanism: don't bother unloading an already loaded but currently unused process from RAM until/unless that RAM is actually required elsewhere, so if the user happens to switch back to it in the meantime then it "launches" instantly with none of the usual delay that an actual reload from disk plus initialization would take. It's no different to the OS using spare RAM to cache commonly-read files, or any of a range of other tricks that modern OSes perform behind the scenes to improve the user experience. If it's working correctly, users should neither know or care; if it's not, they have bigger problems to worry about.

"You can always date old pre-OS X Macsters by the depth of their neurotic obsession with real/imaginary RAM/disk pressure. Hell, they probably still try to reinstall Connectix RAM Doubler after every system update!"

Dude. This has nothing to do with pre-OS X. It really doesn't have all that much to do with OS's.

The big change was the adoption of SSD's. Before SSD's, hitting swapfiles was multiple orders of magnitude slower than hitting RAM. Now, while swap is still slower than RAM, it's not the same kind of massive deal.

In OS X, prior to SSD's, quitting processes to free up inactive memory really did make a user noticeable difference.

@has That’s how it works in theory, but in practice the RAM is not always reclaimed promptly. Secondly, it’s not the same as file caching because it causes functional (not just performance) differences that can break some apps (which I’ve seen happen) or cause confusion. For example, some APIs will report that an app is running, when it’s not actually visible to the user, nor able to receive IPC.

I think this is a good idea in theory, but it sounds like the execution is flawed.

Having two states (open and closed) is already somewhat confusing, so if Apple were to make this less confusing (e.g. all apps are shown as open by default, people can't even quit apps, and macOS automatically manages resources), that would be an improvement. But it sounds like they're adding yet another app state that people have to be aware of, because it behaves in unexpected ways.

@Michael Tsai: From an API point of view, NSRunningApplication gives anything information needed to know the exact stat of the application.

"That’s how it works in theory, but in practice the RAM is not always reclaimed promptly.”

I’m not sure why that RAM would need to be reclaimed promptly. As long as the system doesn’t need it for anything else, let the “zombies” stick around indefinitely. If you really do need that memory recovered for some reason, use /System/Library/CoreServices/talagent -memory_pressure to get the system to take care of it for you.

@Jean-Daniel That’s not clear to me. Where does NSRunningApplication show the napping and zombie state? I did find that it was helpful in that the finishedLaunching property can detect a (different?) kind of zombie process that older APIs could not.

@Brad By “promptly” I meant “when needed,” not “when the zombie is created.”

Leave a Comment