Just to throw in some other viewpoints
Here is a little snippet from Jeffrey Richter's book CLR via C#
............
Richter makes some very good points there.
And, with a CLR that targets multiple platforms, each with its own jit compiler, each jit compiler can employ platform-specific static optimizations for the target platform, in addition to the kinds of dynamic/runtime optimizations done by the jit'er that he gives examples of.
In addition to that, the CLR supports metaprogramming (e.g., Linq.Expression and the DLR), that allow the programmer to generate and compile code on the fly just before execution, and that can be used to for dynamic optimizations as well, based on much more than what the jit compiler knows. For example, a managed application can determine if it is using a data source that's local, or one that's remote, and optimize its processing based on that.
Another reason why I think managed code is going to continue to proliferate is because I think that the future is a lot about metaprogramming (code that generates more code that executes on the fly). If you talk to serious LISP/SCHEME programmers (the ones that use Common LISP, or Scheme), they often find great amusement in how things that are 'new' in each release of the .NET framework, have been in their toolboxes for in some cases, 20-30 years.
Ignoring its other shortcomings for a moment, LISP has no peer when it comes to metaprogramming. In LISP, metaprogramming is so incredibly simple and natural that the programmer often doesn't even realize they're doing it. At the other end of that spectrum are the highly-static languages like C++, Pascal, etc, which are the most difficult languages to do metaprogramming with (it can be done with templates in C++ but it is not simple or easy). The CLR and .NET are somewhere in the middle when it comes to metaprogramming.