Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

If Explorer is killed and then restarted from an elevated process, the final explorer.exe process gets a wrong (low) memory priority #55

Closed
mcdurdin opened this issue Oct 18, 2020 · 5 comments
Assignees

Comments

@mcdurdin
Copy link

mcdurdin commented Oct 18, 2020

Environment

Item Value
OS, Version / Build Windows 10, 10.0.19041.0
Processor Architecture AMD64
Processor Type & Model i7-1068NG7 @2.3Ghz
Memory 32GB
Storage Type, free / capacity (e.g. C: SSD 128GB / 512GB) C: SSD 889GB / 1.35TB
Relevant apps installed N/A

Description

I sometimes need to kill Explorer to release locks on DLLs, etc, for testing. When I do so, I will usually restart it from Process Explorer, which will normally be running elevated. In this situation, the elevated explorer.exe triggers a task to restart explorer.exe at normal privilege level. However, this task launches explorer.exe with a memory priority of 3 instead of 5, which causes performance issues with Explorer and any processes it subsequently launches which inherit this memory priority.

This nearly invisible difference causes all subsequent processes to have a significant performance hit (sad slow builds!), and causes development builds of Chromium to assert and die. I would have had trouble locating this if not for a pointer from @randomascii in the thread at https://twitter.com/MarcDurdin/status/1317385409819676672

Steps to reproduce

  1. Launch Process Explorer and select File/Show details for all processes (elevates procexp)
  2. Find explorer.exe and kill it (Del)
  3. Select File/Run, choose explorer.exe.
  4. explorer.exe will start and terminate, and a new instance starts under the task scheduler svchost.exe.

Expected behavior

The new explorer.exe process should have a memory priority of 5.

Actual behavior

The new explorer.exe process will have a memory priority of 3. You can check the memory priority in Process Explorer:

image

Looking a little deeper, I observed that the elevated explorer.exe creates and launches a scheduled task C:\Windows\System32\Tasks\CreateExplorerShellUnelevatedTask, which shows the following priority setting:

<Priority>6</Priority>

According to https://serverfault.com/a/257183/342637, and verified in testing by me, setting the priority to 4 will give explorer.exe the correct memory priority.

@randomascii
Copy link

To give some extra context, I first ran into this scheduled task issue (or perhaps a restart manager issue, but probably the same root cause) in 2009 or 2010 while working at Microsoft. I then hit it again at my next job. And it's still around.

It can be an extremely painful bug because low memory priority means that a process' working set will be drained and then can easily end up being swapped out to disk. Any programs that are launched from explorer.exe will inherit the low memory priority which can easily end up being most processes the user is running.

When I first encountered it the low memory priority would propagate from explorer.exe to Visual Studio (when I launched it from explorer.exe with a lowered memory priority) and if I didn't use VS for a while it's working set would be drained, and if I left it alone for longer its memory would be written to the page file. This meant that when I went to go use VS it would have to read in hundreds of MB of data from the page file. This was on an old-style spinning disk so this was extraordinarily painful.

A lot has changed since then (memory compression, SSDs) which may change the impact of this bug, but it is still a bug. Thank you for finding a particularly simple way to reproduce it. I hope it gets fixed.

@ChrisGuzak
Copy link
Member

For MS people follow along on the bug here.

@AvriMSFT AvriMSFT self-assigned this Apr 14, 2021
@HelderMagalhaes
Copy link

Caught by this unexpected/undocumented behavior apparently introduced in Windows Server 2016 (I'm on Windows Server 2019):

  • Already using <Priority>5</Priority> to overcome the Below Normal (<Priority>7</Priority>) assigned by default
  • Noticed the unexpected Below Normal memory priority (using Process Hacker, where it's labelled Page priority)
  • Setup two scheduled tasks to assert the behavior:
    • the one with <Priority>5</Priority> got Normal process priority and Below normal memory priority
    • the one with <Priority>4</Priority> got Normal for both process and memory priorities

At a minimum, this means that documentation for Priority (settingsType) Element is incomplete; furthermore, pairs of numbers - such as 4 and 5 - are presented in a way they look equivalent, which is deceiving.

@randomascii
Copy link

The bug (well, some form of it at least) dates back far before Windows Server 2016. I first saw it in 2009 when working on Internet Explorer at Microsoft. We were experimenting with updating IE without restarting the computer, and that required restarting explorer. Explorer would start with low memory priority, so would anything that was launched from explorer, and pretty soon Visual Studio's working set would be drained away to the page file on a slow spinning disk.

The only change since then is that now when the bug hits the trimmed pages are more likely to be compressed or stored on an SSD, so the consequences are less severe.

But, it's still a bug.

HelderMagalhaes added a commit to HelderMagalhaes/win32 that referenced this issue Nov 20, 2021
The relationship between _Task Priority_ and both _I/O Priority_ and _Memory Priority_ is unclear: there are several resources online where this subject has been brought up, usually triggered by unexpectedly bad performance or confused users. The entry which particularly motivated this change request was [Windows-Dev-Performance issue 55](microsoft/Windows-Dev-Performance#55): specifically [comment 932419198](microsoft/Windows-Dev-Performance#55 (comment)).
The values for _I/O Priority_ and _Memory Priority_ were confirmed experimentally, i.e., by creating tasks for all 11 _Task Priority_ values and checking assigned values using [Process Explorer](https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer) and cross-checking with [Process Hacker](https://processhacker.sourceforge.io/).
@AdamBraden
Copy link
Collaborator

The bug mentioned above by Chris has been fixed and in a GA release since 22H2 (22621+).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants