What is mscorsvw.exe and why is it eating up my CPU? What is this new CLR Optimization Service?

[Update – 8/2013] 

Please refer to our more recent post:

Wondering why mscorsvw.exe has high CPU usage? You can speed it up.

The content below is now out-of-date, applying to early versions of the .NET Framework running on Windows XP. 


Short version:

mscorsvw.exe is precompiling .NET assemblies in the background. Once it's done, it will go away. Typically, after you install the .NET Redist, it will be done with the high priority assemblies in 5 to 10 minutes and then will wait until your computer is idle to process the low priority assemblies. Once it does that it will shutdown and you won't see mscorsvw.exe. One important thing is that while you may see 100% CPU usage, the compilation happens in a process with low priority, so it tries not to steal the CPU for other stuff you are doing. Once everything is compiled, assemblies will now be able to share pages across different processes and warm start up will be typically much faster, so we're not throwing away your cycles.

If you are really want to get rid of mscorsvw.exe from your task manager, just do:

ngen.exe executequeueditems

which will drain all the queued up work.

Long version:

If you wonder why I haven't been posting much to my blog, mscorsvw.exe is the reason ;). mscorsvw.exe doubles up as both the CLR Optimization Service (or NGEN Service, as we know it internally) and as the NGEN worker. If you don't know what NGEN is you may start by reading Reid Wilkes' excellent article about NGEN in Whidbey: https://msdn.microsoft.com/msdnmag/issues/05/04/NGen/default.aspx . Reid is one of the members of the team that has been working in NGEN and the Optimization Service.

What problem is the CLR Optimization Service trying to solve?

One problem with precompiled assemblies (I will refer to them as NGEN images) is that they are very dependent on the VM and other asemblies. For example, they have Method Tables in a binary form, know what CLR helpers to call to do various tasks, may inline code from other assemblies, etc...

The downside, of course, is that whenever the runtime (for example via a Service Pack) or one of the dependencies of your ngen images changes (version upgrade or patch), your ngen image becomes invalid. In v1.0 and v1.1 of the CLR we weren't really encouraging people to use NGEN, and this was one of the reasons, nobody recompiled the assemblies if they became invalid, so anybody that NGENed an assembly had to NGEN it again after servicing.

Due to some changes in our long term schedule, we decided after shipping Beta 1 that we had to have a better story in Whidbey for this problem, hence the CLR Optimization Service was born. The CLR Optimization Service will keep track of dependencies of assemblies and will recompile them as necessary. For example, when the .NET Runtime gets serviced, the SP installer will tell the service that there have been changes in the runtime and that it should start recompiling assemblies. Of course, if you have 1000 managed applications installed, that would mean it would take some time to complete the installation of the SP, so instead of waiting to recompile the world, it will compile assemblies in the background.

How does the CLR Optimization Service work?

Reid's article already covers most of this, so I won't extend myself much on this.

There's 2 ways of waking up the service:

- Notifying the service there have been changes that may require recompilation (via ngen.exe update): The service will start up and figure out what needs to be recompiled and will queue up the work that is necessary.


- Queueing up new work (via ngen.exe install /queue): will add new work to the queue of assemblies that need to get compiled.

When does the service do work?

Work is prioritized. There's 2 big buckets of work

- High priority work: Service starts work immediately. Compilation happens in a low priority process to try to minimize impact on other apps that are running. It still can have impact on the machine performance, though, specially if the machine is doing a lot of I/O work or is very low on memory. Currently, priorities 1 and 2 are high priority, but this is subject to change.

- Low priority work: Service starts but waits until the machine is idle. Our definition of idle is something that can change in the future, but I can tell you it looks at things like the last time the user had input, if the machine is running on batteries, screen savers, etc... Once it decides the machine is idle, it will go ahead and do the work that's left.

Once all work is done, the service will shut itself down and won't come back until somebody wakes it up.

What is the typical lifetime of the CLR Optimization Service?

Let's look at the .NET Redist as an example. The .NET Redist does some compilation during setup and also queues up both high and low priority work items. Typically, when the installation completes, you will see 2 instances of mscorsvw.exe running. One is the service itself and the other is the compilation worker process, which is actually doing all the interesting work. If you are curious about which one is which, as a rule of thumb, the one using more memory and CPU is the worker. If you want to know for sure, you can do 'tasklist /svc', which will show you which mscorsvw.exe is the process.

After a while, all the high priority work will get done and you will see only one mscorsvw.exe running. The service is just waiting for the machine to be idle. During this time, the service is not doing anything interesting, so it won't consume CPU and shouldn't be using much memory. One the computer is idle (typically when you take a break or go for lunch), the service will start up new workers to complete the remaining work.

Once all work is done, the service will set itself to manual start (meaning it won't start when you restart your computer) and will shut down.

Should I use the CLR Optimization Service in my installer?

The guideline I would give is the following:

Use /queue in your installer if you have assemblies that you would like NGENed, having the assembly compiled is not necessary for you to meet your performance goals (as with /queue there is no guarantee of when the compilation will actually happen), and install time is very important for you. Rationale: High priority work can impact user experience and with low priority work you  will at least have a service hanging around. Also Idle detection is not perfect (or each person will have one definition of idle), so the best way of having no negative impact on your customer's machine is not having any pending work.

What about 64 bit?

64 bit .NET Redist actually installs 2 versions of the runtime side by side, a 32 bit and a 64 bit one. You get 2 services, but they cooperate to make sure that both are not working at the same time.

Why don't you take advantage of my multiproc machine?

Because we don't want to degrade machine performance. The CLR Optimization service tries hard to do work in the background, having 2, 4 or 8 compilations happen at the same time multiplies by 2, 4 or 8 the memory/CPU/I/O resources we would need.

How do I make mscorsvw.exe go away?

I don't want to wait until my computer is idle, compile everything now!!!

ngen.exe executequeueditems

will process all pending work. Once this is done, the service will shutdown, as it has nothing else to do.

How do I know what is compiled or if my deferred compilation failed?

Look in the Application Event Log, we log there when we start and finish compiling assemblies, and any errors that can occur. We are working on improving the logging for RTM version.

ngen.exe display

Will also give you some status, but is not 100% guaranteed to be completely up to date regarding pending work.


We've worked really hard to get this service done for Beta 2. One of the mean reasons to do this is getting feedback from our customers, so let us know your opinion, concerns, or if you see anything suspicious or that looks like a bug let us know about it: https://lab.msdn.microsoft.com/productfeedback/ (we keep better track of bugs/suggestions that come from there, so while you're free to use the blog to do that, I recommend you doing it via the feedback site)

I'm posting this now because I have seen already questions in the newsgroups. Let me know if you have any other questions. I'll also be updating this post as things come up

[Update Jun/17/2005]
After investigating some machines that were having issues with mscorsvw.exe, we've found a problem that occurs when you have 2 builds of the CLR installed (typically a Whidbey Beta 2 and a CTP). This configuration was never supported (we don't support side by side builds of Whidbey) and other things are broken. The underlying cause of the problem is that we're not COM compatible between builds (only between major versions, for example: Everett and Whidbey's COM interfaces are compatible) and setup is not updating type libraries correctly in this scenario.  I asked our Setup team to address this issue (by telling the user that side by side builds is not a supported scenario or disallowing the installation) and it will be addressed in the future (due to schedule limitations, it's not possible for them to do this work in Whidbey timeframe). We also have done work to ensure that even if we run into the scenario, we terminate gracefully

Typical symptoms of this problem include mscorsvw.exe permanently taking 100% CPU. If you try doing 'ngen.exe display' (using the Whidbey ngen.exe) and get a E_NOINTERFACE error you are hitting this issue. I recommend you cleaning your machine (as there may be other CLR stuff that is broken), but as a workaround you can go to the services panel (services.msc) and disable the service or do it via command line:

Disabling NGEN Service for Beta 2 build (for other builds, substitute 50215 with the number of your build)


      sc.exe stop clr_optimization_v2.0.50215_32

      sc.exe config clr_optimization_v2.0.50215_32 start= disabled

      sc.exe stop clr_optimization_v2.0.50215_64

      sc.exe config clr_optimization_v2.0.50215_64 start= disabled

I apologize for any trouble this may have caused.

[Update Sep/19/2005]
Some folks have also reported mscorsvw.exe problems in Vista Beta 1. There's 2 problems people are seeing here:

- Same as problem described above, but caused by installing Betas, CTP or RC builds on top of Vista. Vista has already installed a Whidbey build, so if you install another CLR build on top of it, you may break the Whidbey build in LH (or viceversa). Once Vista has final Whidbey CLR bits, the problem will go away, as trying to install RTM Whidbey on top of Vista will result in a no op. We tried to get in some changes so that the MSI installers refused to install on Vista (it's a non supported scenario to have any other Whidbey build than the one that comes with the OS), unfortunately, it was too late to do this. Again, as a workaround, you may want to disable the service and make the problem go away, but there is possibly other stuff broken (such as the debuggers or any other COM based infrastructure the CLR has)

- mscorsvw.exe kicks in when the machine is not idle. Due to recent changes in Vista in how services run (they are now run in a different session), the idle time detection of NGEN Service doesn't work well in Vista Beta 1, as it cannot see user's  input, declaring the machine as idle before it should. This has been addressed in our RTM release (which will probably make it for Vista Beta 2). Also, note that not all service work is meant to be done at idle time. In Vista, some of the high priority work happens during setup/first boot, then the low priority work happens at idle time.