WindowServer is hungry for memory on M1 Macs

Several of you have reported that WindowServer hogs your CPU, and may consume large amounts of memory too. A few have suggested it might have a memory leak, although no one has provided any evidence to support that. This article looks at WindowServer’s use of resources in Monterey 12.2.1, on both Intel and M1 Macs, to see if there’s evidence of a problem.

To assess this, I looked at the CPU % and memory usage given by Activity Monitor for the WindowServer (WS) process on two Macs: an iMac Pro with 32 GB of memory, Radeon Pro Vega 56 8 GB graphics and its standard 5K 27-inch display; an M1 Pro MacBook Pro with 32 GB of memory and its standard display. Both were set at their default display resolutions, and had been freshly restarted in Monterey 12.2.1 before testing. Web pages used were rich in content, with static images and text, but none contained streamed video or similarly demanding media. Safari windows had full options, including the Bookmarks sidebar, Favourites and Status bars, and occupied the majority of the screen.

Results: Intel

When freshly started up with a single Activity Monitor window open, WS used around 1% CPU and 154.6 MB of memory. Adding two large Finder windows increased memory use slightly, to 158.2 MB, but didn’t affect CPU.

Safari, with a single page open, either its Start Page or a website, had no effect on CPU, and increased memory usage to about 165 MB. Adding further Safari windows steadily increased both CPU and memory usage:

  • 5 windows CPU 4.3% 172.7 MB
  • 10 windows CPU 5.0% 181.8 MB
  • 20 windows CPU 5.6% 198.6 MB

These give a good linear regression with an overall memory cost of 1.7 MB per Safari window.

When all 20 windows were minimised into the Dock, CPU fell to 1.2% but memory increased further to 214.1 MB. With all 20 converted to tabs within a single Safari window, CPU remained at 1.2% and memory fell back slightly to 207.2 MB. Closing that window and quitting Safari returned WS to 0.9% and 185.8 MB memory usage, leaving the latter slightly higher than it had been before Safari had been opened (158.2 MB).

Results: M1 Pro

With a single Activity Monitor window open, WS was slightly more demanding in its CPU and memory use than on the iMac Pro, with 2.1% CPU and 192.1 MB memory. These increased slightly with two Finder windows, and with Safari displaying its Start Page or website in a single window. What was unexpected was the significantly higher use of resources with increasing numbers of Safari windows:

  • 5 windows CPU 20.2% 476.5 MB
  • 10 windows CPU 26.4% 732.2 MB
  • 20 windows CPU 17.2% 1230 MB

Linear regression here gives an overall memory cost of 50 MB per Safari window, thirty times that of the Intel Mac.

Minimisation of all 20 windows again reduced CPU usage, to 2.3%, but didn’t change memory usage at all, which remained at 1230 MB. Effects of collapsing all 20 windows into tabs in a single window were similar to minimisation. Closing that window and quitting Safari returned WS to 2.4% CPU and 304 MB of memory, the latter being higher than at the start (211.5 MB) but much lower than its high tide mark.

Discussion

WindowServer appears to perform well and economically on the iMac Pro, with 8-core Intel CPU and graphics card. CPU and memory usage grows slowly, making it feasible to have plenty of windows open and active.

Results of increasing Safari windows on the M1 Pro were a complete surprise: CPU use appeared higher, reaching more than 25%, and memory used grew to well over 1 GB, more than five times that of the Intel Mac. However, as most if not all of this CPU load was borne by the two E cores, those figures for CPU % may be misleading, as they don’t take into account the operating frequency of the cores, making comparison with Intel figures impossible.

At an overall 1.7 MB per window, WS memory cost of open windows in Safari is modest on the Intel iMac Pro. That contrasts with the figure of 50 MB per window on the M1 Pro, which is thirty times greater. This is so marked in Safari that I checked in other apps including Pages and Numbers, which were more modest in their demands. This difference between Intel and M1 Pro Macs is apparent even when individual windows only contain the Start Page.

Even more surprising is the lack of any memory saving when open windows are minimised into the Dock, or converted to tabs in Safari. However, working with tabs instead of windows from the start didn’t result in significant additional memory use.

Conclusions

  • On (at least some) Intel models, WindowServer is frugal in its use of resources, requiring as little as 1.7 MB for each additional window in Safari.
  • On (at least) the M1 Pro, WindowServer uses an additional 50 MB for each window. It’s not clear why this is so much greater than on Intel.
  • Minimising windows into the Dock saves on CPU demands, but doesn’t alter memory use at all.
  • Converting existing Safari windows into tabs doesn’t save any memory, but working with tabs in the first instance does.
  • Interpreting CPU % on M1 models isn’t easy, as core frequency is critically important, but not available in Activity Monitor at present.
  • Opening large numbers of windows on M1 Macs may adversely affect their performance greater than on Intel models.
  • There’s no evidence here of significant memory leaks in WindowServer.

If you can explain why there’s such a great difference between Intel and M1 Macs, I’d love to hear from you in a comment.

Speculative Postscript

Thank you for the suggestions, in comments here and on Twitter, that the reason for this difference is the M1’s use of Unified Memory. Yes, that has been at the back of my mind throughout. However, I don’t know enough about WindowServer to know whether that’s reasonable. I had thought that WS is primarily concerned here with compositing rather than rendering, in which case what it does, and the memory requirements, shouldn’t differ between the two architectures.

However, it might be that the windows it composites for some apps, like Safari, already contain much of their content rendered, and that can therefore be shared direct with the GPU under the Unified model. That still doesn’t explain the large differences in memory usage by the WS process. There also doesn’t appear to be any way in Activity Monitor to discover how much memory is being shared in that way.

So the obvious answer is that differences are due to Unified Memory, but that doesn’t explain how or why.

It’s also important not to assume that the M1 Pro does have higher CPU usage for the same tasks; without information on core frequencies, using CPU% from Activity Monitor is completely misleading, and the higher percentages reported could actually reflect the same rate of instruction retirement, for example. Unfortunately obtaining reliable measurements of core frequency for WS usage isn’t easy.