Often the .NET Common Language Runtime, or CLR, is directly compared to the Java Virtual Machine. Initially, there are many clear parallels: both are “managed” environments that provide a component container, both consume a “partially chewed” intermediate language, both provide low-level services like garbage collection and threading conveniences.
[Scott Hanselman]
Sun promotes a marketing program called 100% Pure Java, which is certainly appropriate if code portability and underlying operating system transparency is a desirable endpoint.
The Java VM is truly a “virtual machine” that’s ultimate goal is to abstract (virtualize) away the underlying Operating System and provide an idealized (not necessarily ideal, but idealized) environment for development.
The .NET Common Language Runtime is named well as it is used more as a Language Runtime than a Virtual Machine. While it successfully abstracts away aspects of underlying hardware through its use of an Intermediate Language, when the CLR is combined with the .NET Framework Library of APIs it is married to the underlying platform, which is Windows. The CLR provides all the facilities of the Windows Platform to any .NET-enabled Language.
If Microsoft were to truly virtualize the machine, they would have marginalized their investment in the Windows platform. The .NET Framework Library itself isn’t “pure .NET” as it takes every opportunity to take full advantage of the underlying platform primitives.