Realtime performance and low-level data structures are also a problem with an interpreted language that uses garbage collection.
For example, National Instruments, which builds data acquisition hardware, switched to .NET for their libraries a few years ago, and depreciated all other interfaces. Because that was the new, required development platform. And they really did a great job in building a new library the correct .NET way.
Unfortunately, there is no way in .NET to do accurate timing or handle events within a certain (small) time window. Which made it really hard to use their hardware (plug-in boards) to do what it was supposed to do: measure accurately. Because you don't know how much "CPU" time your app is going to get, and when. And all bets are off when the GC starts it's sweep.
They solved that problem by switching to a different line of products: external rack mounted modules, with their own processor and OS in the rack. So they can still offer the .NET library.
And without pointers, strings being unicode exclusively and no direct control over how, when and where your datastructures are created, their memory layout, or the ability to travel them in the lowest latency possible, communication with many devices becomes erratic at best, and there is no way to meaningful profile your functions to run within the allotted time.
And, while much of the abstraction went in the ability to painlessly being able to write multithreaded apps, it still only works when you know what you're doing. Which has become a lot harder because you don't know how or can predict how the runtime is going to execute it all.
In short: the most the abstraction has done is to make it harder to figure out what is really happening.
Then again, with the focus on webapps and there being such a mountain of stuff underneath your application, it stands to reason to try and simplify it as much as possible. But then again, that only works if you never have to travel outside the bounds. So, each and every interface and piece of attached hardware should be integrated and abstracted, through a common interface. Which only works if you'll never use the extra functionality it has to offer.
That's the main reason it works so well for webapps: a browser is a pretty closed virtual machine. Like a console. There are some differences you need to take into account, but they're both pretty fixed.
So, the main programming market has mostly split into light, high-level webapps (the main bulk), electronics, embedded devices, tools, games and server services (for the experienced die-hards) and architecture/integration/communication/management (for the problem solvers and managers).
What we need is a common language, that runs in all of those environments. Something that allows you to describe the project, keep track of it, write the code, add, use and animate the art and other assets, test it, compile and link it into the files needed for the application to run, be it native code, JavaScript, Flash, Java or whatever.
But .NET isn't it.