Some Like It Hot
Ask Cupertino how hot it is. Remember that your Mac is your friend.
Macs can get hot, says Jonny Evans, over at Apple Must. Of course they can. Some Macs run better in a fridge, and users protect their laps (and their clothing) from Mac laptops. Of course they do.
Jonny might be talking high-octane, so one can't know how serious the issue is with recent products. And no one here is going to invest any more in Apple hardware until the company can get some shit fixed, with proper management and a better CEO.
Obsessions with 'thin', and consequently no lid light or MagSafe adapter. Stubbornness in scuppering the amusing Touch Bar, and don't touch your screen like you do on mobile, even though it's made to be touched: you get the idea that there's 'political correctness' at Apple? Of course you do.
Now they want image files sealed with their root certificate to pass Macintosh muster, social media sites and competing music vendors are harassed, the New York Times condemned them, no more ports on the laptops, you gotta carry around a tote bag with dongles (which of course Apple will sell to you at a very fair price).
That's a company only a fanboy can believe in, no matter the vestiges of brilliance in a technology they have never and will never understand (but somehow acquired and subsequently abused).
So we have to take Jonny's word for it. Which, for the purposes of this meaningless little piece, is good enough.
For the record: Jonny's been into 'Mac' since 1999. At what capacity isn't known, though it's likely he's not a developer or real guru, as we really don't have time to write pretty pieces for the MSM. But even so. Let's listen to him.
Jonny was working on a video clip and noticed that his Mac had slowed down. Note: Jonny's not using a computer. He's using a Mac. There's a big difference. We've felt it too. One of us actually considered bedding down with her new laptop at one point. (But that OOTB rush passed fast enough. And it certainly didn't last twenty years.)
Macs are complex machines, says Jonny. This is important to point out. In contrast to IBM z-Series mainframes, for example, which are relatively simplistic. (Of course they are.)
Kernel tasks are low-level tasks, explains Jonny. To be more explicit: the 'kernel_task' process is a key process running hundreds of threads. Anyone wishing to go deeper into that might start with studying the original code by Ken Thompson or the closest one can get, then move on to studying microkernel architecture in general and MACH and XNU architecture in particular. But yes, they're low-level. Nearly rock-bottom.
Processors today run in two distinct modes. At least two. Intel had a name for these modes: they called them 'rings'. The most important thing is to realise that two modes are necessary today.
It's not easy to summarise what goes on here. The two modes can be called 'user mode' (that's you) and 'kernel mode' or 'privileged mode' (that's your
User mode is where you work. As a lowly user. It's where you 'interface' with your applications. User mode seems to have vast memory capabilities. Much more RAM than you actually have.
Operating system kernels have to quickly change the processes they're running - yes, right in the middle of things. All the time. They use a time unit often called a 'quantum', a very low number of milliseconds. This is the 'preemptive multitasking' you hear about.
Old 'beige' computers from Apple didn't have preemptive multitasking. They had to hope that everything running there would voluntarily relinquish control often enough - something called 'cooperative multitasking'.
But that's behind us all now. The kernel yanks out running code in a running process, swaps it out so to speak, for another thread in perhaps another process, and gives it time to run too. This is how modern computers can keep up the illusion that 'everything is happening at once'. Even lower down, at device driver level, code has to defer execution of code ASAP, often leaving important tasks ('deferred procedure calls') until later.
All to keep things running smoothly. The illusion that everything is happening at once when it's not.
('How many threads are running here, Yossarian? One? Did you say 'one'? You're cured!')
Those device drivers, the kernel itself, run in kernel mode. User mode can't see the physical resources. Can't see your keyboard, can't see any of the hardware in your
computer Mac, can't see your Touch Bar (yes what a good life it must be) and can't see your memory either. All your user mode apps are written as if they believe they actually do see your RAM. That's the point. The kernel has things known as 'page tables', something that's not possible with less than a 32-bit processor. You have to be able to address real memory and also know a bit of where that comes from. Physical memory is chunked up in pages, where a page is the smallest chunk of RAM that can be 'swapped'. This is normally 4 KB today.
Your software thinks it sees physical RAM but does not. The system used - and it's a cornerstone of this technology - is called 'virtual memory'. What your applications see is memory alright - virtually at any rate. When your software attempts to access what it thinks is real memory, your processor looks at the request, finds the pertinent entries in the page tables, goes and gets the real RAM memory for the operation, and returns the results. Your program is none the wiser. And that's why it works.
Kernel mode threads can see actual RAM. They can see your keyboard. (Unfortunately they can also see your Touch Bar.) They can see your devices and your actual physical memory. Naturally their code is very sensitive. This code cannot fuck up. That's a big no-no. Kernel mode code is not the same as writing programs in BASIC for a beige box. Testing is consummate. Coding practices are excruciatingly meticulous. Best to leave that job to those who enjoy it. And be grateful some seem to enjoy it.
kernel_task is where all this kernel code is channeled. As needed, your CPU will flip from user mode into kernel mode. This will happen in the middle of your ordinary applications. They'll flip into kernel mode, and control in your application delves down into the deep. (And returns as fast as it can.)
This screenshot shows kernel_task (process 0) soaking up 1.75 GB of real memory, attesting to virtual memory for 69.50 GB, using 1.74% CPU, and not hanging a single time (yay).
This screenshot, taken a few seconds later, shows kernel_task getting ambitious again, using 3.46% CPU (about twice as much). Still no hangs, but here, on the other tab, one sees a lot of useful info.
kernel_task runs services on the part of user mode code. The thread count means essentially that kernel_task has 142 clients. Par for the course. The CPU time is neither here nor there, but the number of context switches is not.
'Context Switches: 101276132'
(AM must have been built before the Good Samaritan at Apple decided to put commas in numerical fields?)
Context switches: 101,276,132. Over one hundred million. Again: what is a context switch?
A context switch is what happens when a preempting system temporarily stops running one program and, for another brief moment, runs another. Everything has to be stored for safekeeping before the 'switch'.
The contents of all CPU registers have to be stored somewhere for the time being.
The CPU has to remember things like the stack pointer, the instruction pointer, keep track of the stack so temporary variables can be found again.
And so forth. And that's only the half of it, for the reverse is needed for the incoming thread too.
This can happen thousands of times per second. It's the context switch: the context in which code is run.
[As applications are part of the overall multitasking scheme, so are parts of any ongoing process, so that a process - a single program loaded into memory for execution - can itself be trying to do multiple things 'at once'. Those 'things' it's doing are called 'threads'.]
A fault is not a fault. It is not an error. Let's revisit the idea of virtual memory. Virtual memory is not real memory - it's virtual. It pretends to be real memory. Call it fake memory? Whatever. It pretends to be real. It effectively extends the capabilities of the computer hardware. But that's only the beginning of it.
When a program is loaded into memory, it becomes what's known as a process. This process and its threads get swapped out of memory all the time. But to where? To disk of course. Your system will have one or more 'swap files' already early on.
What's important to understand here is where it all begins. Does the program code originally reside in memory, and from there get swapped out to disk when needed? Or does it originally reside on disk?
This seems to turn everything topsy-turvy, but it doesn't. Things originally reside on disk - that's where the system originally found it. Preparing an on-disk program to run as a process can be a very fast business: mark a few flags here and there and you're ready.
But what happens when this new process wants to access stuff in memory? Where does it find its code? Where does the code find its variables?
The page fault.
The CPU's page tables indicate that something that should be there in memory is not in fact in memory. The CPU looks at the request for super-long unsigned integer FOO, looks it up in its pages tables, and can't find it. So it generates a page fault (a kind of 'interrupt').
A page fault isn't something wrong - it's how virtual memory works. The virtual memory representation of a process 'loaded' to run is the actual program file on disk. Everything starts on disk.
Programs have both read-only code ('TEXT' curiously) and DATA that will change over time. Pages of the program with data will be marked 'copy on write', meaning that the CPU will remember this, so as soon as something in the program wants to change a variable, it can't be written back to disk, as that's the original program file and it can't be corrupted, so the CPU (the kernel) will have to start using the dedicated swap file(s) to store it. This change of course goes into the page tables so the system knows where to fetch that page next time around - it's no longer the original program file on disk, now it's over there, in swap file so-and-so, at offset blah-blah, and so forth.
Clear as mud? The important thing to realise is that, in the world of multitasking, virtual memory is far far more than a way to extend hardware capabilities. Such an explanation is misleading.
Running all those kernel services in threads rather than new processes can have an advantage above and beyond being more straightforward: even the kernel can have global state variables that don't need to be part of the context switch, consequently speeding things up.
Back to Jonny.
'From the moment you switch your Mac on to the moment you switch it off, most every task your Mac does will go through kernel at some point.'
Meaning what? Most likely he's only trying to impress on you how important the kernel is.
'The tasks are many, but your Mac sees them all as kernel_tasks in Activity Viewer.'
Well actually it's one process with a lot of shit running inside it. As readers here hopefully know by now.
'In normal use, your Mac probably isn't using too much processor power.'
Then why did old 'MacOS' crash reliably when it was idling? Asking for a friend.
'If your Mac seems slow in normal use when you aren't engaged in a complex task, you can usually get it back into tip-top shape by restarting your machine.'
Sidesteps the inevitable question 'why'.
'It's possible one or more applications or processes just hasn't [sic] relinquished memory for some reason. Restart makes this happen.'
Answers that question. Sort of. The question is how a process in a multitasking system today can hold onto memory once it's booted out of the CPU for good. It can't. Any program can leak memory while running. But those leaks won't pertain to the system as a whole.
But if it's some of Apple's own resident code, on the other hand... And Apple's code in fact indeed is leaky. Try running leaks on your 'core' user mode apps.
Process: Dock  Path: /System/Library/CoreServices/Dock.app/Contents/MacOS/Dock Load Address: 0x10cb05000 Identifier: com.apple.dock Version: 1.8 (1963.6) Build Info: Dock-1963006000000000~12 Code Type: X86-64 Parent Process: ???  Date/Time: 2019-07-09 11:45:47.114 +0200 Launch Time: 2019-07-09 02:32:26.638 +0200 OS Version: Mac OS X 10.14.5 (18F132) Report Version: 7 Analysis Tool: /usr/bin/leaks Physical footprint: 54.6M Physical footprint (peak): 110.0M ---- leaks Report Version: 4.0 Process 280: 39142 nodes malloced for 81951 KB Process 280: 35 leaks for 3696 total leaked bytes. 35 (3.61K) << TOTAL >> 5 (528 bytes) ROOT LEAK:  3 (224 bytes) 0x6000011cfca0  length: 4 "nrre" 1 (96 bytes)  1 (96 bytes)  1 (96 bytes)  5 (528 bytes) ROOT LEAK:  3 (224 bytes) 0x6000011834c0  length: 4 "nrre" 1 (96 bytes)  1 (96 bytes)  1 (96 bytes)  5 (528 bytes) ROOT LEAK:  3 (224 bytes) 0x6000011f56e0  length: 4 "nrre" 1 (96 bytes)  1 (96 bytes)  1 (96 bytes)  5 (528 bytes) ROOT LEAK:  3 (224 bytes) 0x6000011ed420  length: 4 "nrre" 1 (96 bytes)  1 (96 bytes)  1 (96 bytes)  5 (528 bytes) ROOT LEAK:  3 (224 bytes) 0x6000011ed7c0  length: 4 "nrre" 1 (96 bytes)  1 (96 bytes)  1 (96 bytes)  5 (528 bytes) ROOT LEAK:  3 (224 bytes) 0x6000011cf340  length: 4 "nrre" 1 (96 bytes)  1 (96 bytes)  1 (96 bytes)  5 (528 bytes) ROOT LEAK:  3 (224 bytes) 0x6000011ee7e0  length: 4 "nrre" 1 (96 bytes)  1 (96 bytes)  1 (96 bytes) 
So yes, you'll get that memory back if you reboot. But that's normally not a lot of memory. It's still inexcusable, sloppy even, especially coming from an OS vendor, but it's not that much memory.
A bigger culprit is the physical virtual memory itself: the actual on-disk swap file(s).
Apple got out of trouble here, as most recent hardware uses SSD instead of HDD and SSD is so much faster, but, to put it politely, Apple's VM management has never been stellar. It's slow, it's sluggish, all VM systems can get that way, but Apple's has been particularly so.
And as you run longer and longer, with more and more apps that force things into the dedicated swap file, things can get very bad. That swap file on disk never goes down in size. Hard drives are slower than RAM by an order of magnitude, measuring access in milliseconds rather than microseconds or nanoseconds.
'However, when you ask your Mac to do something more strenuous - such as transcoding video - then [the] kernel will rush to reassign tasks.'
'Reassign tasks'? But no. No. That's not the way it works. See above. You really think it's like this?
'Oh goodness that Mac is in trouble again, best we jump in and run a bit of its code! Come on, guys!'
'If the kernel identifies that your Mac is running hot while engaged in a difficult task, it will take steps to manage temperature.'
This is a new one. It should be looked into. (If one cares anymore about Cupertino, which is increasingly unlikely.)
'This behaviour isn't always generated by ostensibly challenging tasks. Some advertising and poorly built websites can force similar reactions by stretching Safari.'
Safari's a mess. Look through its history for more than ample examples. Safari's a memory hog.
Process: Safari  Path: /Applications/Safari.app/Contents/MacOS/Safari Load Address: 0x10e63e000 Identifier: com.apple.Safari Version: 12.1.1 (14607.2.6.1.1) Build Info: WebBrowser-7607002006001001~3 Code Type: X86-64 Parent Process: ???  Date/Time: 2019-07-09 12:15:00.343 +0200 Launch Time: 2019-07-09 02:34:19.066 +0200 OS Version: Mac OS X 10.14.5 (18F132) Report Version: 7 Analysis Tool: /usr/bin/leaks Physical footprint: 67.4M Physical footprint (peak): 88.0M ---- leaks Report Version: 4.0 Process 411: 199170 nodes malloced for 60446 KB Process 411: 275 leaks for 33968 total leaked bytes. 275 (33.2K) << TOTAL >>
'Flash was always a culprit. Facebook is usually a culprit.'
Yes. Flash runs codecs in software. It's gone. Facebook, as anyone who's looked knows, is a mess. Yes. Truly. (Are you surprised?)
'Try not to open too many concurrent tabs.'
Keep it down to one tab?
'What can I do to help my Mac stay cool?'
Ah. Here we go. The ulterior motive for even looking at this piece.
Once again, not the first time and certainly not the last, we'll find Mac users saddled with the responsibility of compensating for what Apple should have done.
So Jonny, good intentions to be sure, offers the following.
'If using a MacBook-type Mac, get yourself a laptop stand.'
Absolutely. Best to dress in an eskimo coat and place your Mac on a tray of dry ice. Be kind to your Mac.
'Clean your Mac regularly, and check the air vents.'
Absolutely. And try not to breathe onto your Mac. Avoid garlic and onion.
'Get a cooling pad - many of these include built-in fans, which helps keep your system cool.'
See #1 above. You do not, repeat DO NOT, need a pad or a fan. Stop complaining like an Apple-hater and go out and get that eskimo coat and the dry ice - it's a Mac!
'Try to ensure you don't block the air vents on your Mac, and leave plenty of space around it on your desk, because: AIR FLOW.'
Yes. Because: AIR FLOW. Of course, an alternative is to put the box near an air-conditioning unit. But if you've already got the dry ice, hey...
Or try resetting the SMC, says Jonny.
So why is kernel_task CPU activity so high? Why? As Jonny asked.
For that's the ultimate question. Jonny offers a number of tricks to get things relatively back down to a modicum of normalcy (sanity). This is good. Thank you, Jonny. But why should this happen? We can visit Louis Rossmann later - let's look at the system end of things for now. For things are bad in absolute terms on this
computer Mac. Why? Why? Why?
OK, a quick crash course lesson for the fanboys. Fire up Terminal and run 'top'.
Note the values up there. Near the top. (Near the top of top.) (Don't worry: they don't move - 'Unix wizardry'. Or try uptime instead.)
Load Avg: 6.74, 2.27, 0.87 CPU usage: 2.21% user, 2.21% sys, 95.56% idle
The load averages, on an ordinary Unix
Mac computer, should be under 0.50. Under 0.50. Way under.
But they're not under 0.50 on your
computer Mac. Why?
Ask Cupertino, fanboy.