Why Managed Code Is Safer

One of the biggest sea changes in computing took place in the late 1990s, with the switch over to running managed code, first with Java and then a couple of years later with .NET. Prior to this, compiled code (typically written in C, C++, Visual Basic or Delphi/Pascal) produced unmanaged code. Yes, both of these run machine code. So what’s the difference?

Unmanaged Code

Unmanaged code is just low level code (machine code) that the CPU (Central Processing Unit) executes directly. It can come from any language before being compiled to machine code and the resulting binary files can range from very small programs under a hundred bytes to large applications hundreds of megabytes in size.

Languages that produce unmanaged code must provide library routines through operating system calls statically linked into the executable or in dynamically linked libraries — called dlls on Windows, or .so on Linux.

The big advantage of unmanaged code is that it’s “closer to the metal.” It’s used in time critical situations in operating system drivers for peripherals, or embedded code. It doesn’t require a full framework to support it, so it can have a very small footprint. Games in particular run fastest if they run as unmanaged code.

Unmanaged code typically doesn’t have full control of the computer except for the programs that are part of the operating system that run in kernel mode. This provides hardware level protection but means programs that run in kernel mode need to be well-written, as they can crash the PC. User programs, however, almost always run in user mode. They can crash or run out of memory, but they won’t affect the rest of the system and, more importantly, won’t affect the operating system code and data.

Managed Code

Managed code means that the compiler produces intermediate code targeted at a virtual machine (VM) instead of native machine code. In Java, programs are compiled to bytecode and output to Java classes and jars (archive files). In .NET languages, code is compiled to .il (Intermediate language), and stored in assemblies. Both Java bytecode and .NET assemblies are highly portable: Any machine that has a compatible VM can run that code, regardless of whether its CPU is 32 bit or 64 bit. In .NET, the VM is called CLR, short for Common Language Runtime (in Java, it’s the JVM).

The intermediate code can’t be run directly by the CPU like unmanaged code is. When the VM (a program in its own right) “loads” an application, it converts the intermediate code into the native code of the real CPU and either runs it or translates it into calls to the underlying platform’s functions (known as interpretation) and then runs it. Translation to native code can incur slight delays in start-up.

Programs that compile to managed code are not quite as “near the metal.” For the very fastest programs, you’ll want to run your program in an unmanaged environment. So, programs written in C++ will be quicker than Java or C# programs, though the difference is small these days. Much of the difference depends on the optimizing ability of the compiler and the virtual machine that underpins the managed environment.

However, managed code has lots of advantages. Running in a managed environment, the code is checked to be safe and can’t crash the machine. The VM can also provide garbage collection, so you never have to write memory management code to free up allocated blocks. Virtual machines like ‘HotSpot’, the most popular JVM, monitor performance and use optimizations to improve the execution speed while a program is running.

Possibly the biggest advantage of managed code is the supporting code provided in the frameworks, which can keep down the size of managed code. In .NET, for instance, there’s a massive number of classes, somewhere in excess of 12,000 for .NET 3.5. Having them all in one place (the framework) is a lot easier than having to juggle dependencies between different libraries, which is how it works in C++ (and to a lesser extent, Java).

So while you pay a little price in performance, you gain extra safety by moving from unmanaged to managed code.

Multiple Languages

Because managed code compilers target a specific platform (.NET or Java), the languages that they compile share the libraries built into that platform. There are nearly 30 different programming languages that compile for the JVM, and a similar number for the CLR. That means that in both cases, there has been much less reinvention of the wheel for common features like string manipulation and networking.

Example

Here’s an example of C# code in each of the three stages.

As C# code:

C# Code Screenshot

As .Il code:

C# Intermediate CodeIn machine code:

C# as Machine Code

 

Comments

  1. BY Jason Thorpe says:

    Why is the machine code screenshot from Java? The first two were in C#, so it would make sense to show third also in C#.

    • BY Ravi Bhavnani says:

      > Why is the machine code screenshot from Java?
      What makes you think it’s from a Java app?

      –Ravi

      • BY Jason Thorpe says:

        I stand corrected. I did not see the .cs extension on the end. What utility did the author use to show the machine code?

        • BY Aaron Johnson says:

          I actually thought it made a lot of sense to show the machine code. He talked about the logical progression from source code to intermediate language to machine code in his article. Why _not_ show the machine code?

          • BY Aaron Johnson says:

            Darn it, now let me correct myself. I didn’t really read your comment carefully. What I thought I read was “What utility (purpose) did the author have in showing the machine code?”

            My bad.

            On that note, however, I also would like to know what utility the author used to show the machine code.

    • BY Anonymous says:

      The directory is java, however the program is actually C# as can be seen by the .cs extension.

  2. BY Lubo says:

    Just to complete the story – managed code has been around for much longer (although ‘managed’ is a term that only Microsoft uses). Pascal and other languages (I think it was Turbo C++) could compile to p-code at least as early as the 80′s, and Smalltalk ran in a VM since the 80′s too. In fact, Java and C# owe a lot of their best features to Smalltalk.

  3. BY Marc Clifton says:

    “Unmanaged code is just low level code (machine code) that the CPU (Central Processing Unit) executes directly. It can come from any language before being compiled to machine code”

    So, in other words, “Unmanaged code == machine code” thus “Unmanaged code can come from any language before being compiled to unmanaged code”. Or “Machine code can come from any language before being compiled to machine code”.

    So, pretty meaningless statement.

    Next… “Languages that produce unmanaged code must provide library routines through operating system calls” deserves a serious WTF are you talking about. What does “library routines through OS calls” mean?

    Next…” Running in a managed environment, the code is checked to be safe and can’t crash the machine.”

    Riiight. Have you ever used a managed environment that tries to load gigabytes of, say, image data, on a system with 2GB RAM? Something will definitely “crash”.

    • BY Richard says:

      “Have you ever used a managed environment that tries to load gigabytes of, say, image data, on a system with 2GB RAM? Something will definitely “crash”.”

      With managed code, the application will crash, but the OS will continue running. (Assuming your managed code doesn’t call buggy unmanaged code like GDI+, in which case all bets are off.)

      With unmanaged code, you could overwrite memory that doesn’t belong to your application, causing other programs – or even the OS – to crash. You could also end up writing data to executable memory, creating a major security hole.

  4. BY Harold says:

    You showed the disassembly of unoptimized code, ie ran in a debugger with “suppress JIT optimizations” enabled (which is the default).

  5. BY Derek Hunter says:

    “In .NET, for instance, there’s a massive number of classes, somewhere in excess of 12,000″

    You say that like it’s a good thing!

    The thought of wading through all those trying to work out dependencies and hidden side effects fill me with horror. But I’m just a C programmer with a fondness for malloc() and free() and a great fear of third-party libraries.

    • BY Herbie says:

      I used to worry about learning Java libraries and classes too. It put me off Java completely. However I find with C# and a decent IDE that it is so much easier. I use VS2008 (still) as I find the Intellisense extremely useful.

      If I had to write code using notepad or some other dumb editor then life would be harsh indeed.

  6. BY Anirudha says:

    Managed code(.net) can be completely converted into unmanaged machine code using NGEN..!

  7. BY vic says:

    I’d like to add the following in addition to Marc’s remarks ;)

    about “unmanaged code” :”User programs, however, almost always run in user mode. They can crash or run out of memory, but they won’t affect the rest of the system and, more importantly, won’t affect the operating system code and data.”

    and now about “managed code”: “However, managed code has lots of advantages. Running in a managed environment, the code is checked to be safe and can’t crash the machine.”

    so the advantage of managed code is that it can’t crash the machine – same as what you say about unmanaged userspace code.

  8. BY Eugene says:

    Oh, my god!

    Walking on your 2 feet is also dangerous – you can fall!

    Walking in a baby walker – much safer!
    You walking will be slow and mediocre – but quite safe.

    Good luck, Baby.

    • BY PK says:

      Bad analogy Eugene. In what sense do you mean slow and mediocre? Managed languages like Java and C# are demonstrably more productive than unmanaged languages, simply because they free you of the considerable burden of tracking and managing memory safely. Or do you mean they are slower at runtime? That isn’t always true either – startup times are slower, but the JIT for a VM has the big advantage that it can optimize based on the runtime performance; paradoxically managed code can sometimes actually run faster than compiled code where all optimizations must be done ahead of time.

      C++ and C are these days superior to managed languages for some uses but not all; for example, when you *really* do need to manage memory manually, because you need a precisely definable footprint, or because you can’t afford the garbage collector kicking in at unpredictable intervals.

      So, a better analogy might be ice skates vs trainers. Most of the time, trainers are going to be easier, safer, and quicker to walk in. But if you’ve got an icy surface, the ice skates are now superior, and will enable you to go much quicker than the trainers (provided you can ice skate).

  9. BY gkb says:

    Actually Frameworks such as SAP ABAP or Cool Gen or IEF or Salesforce is better. They increase developer productivity a lot and easy to debug.

  10. BY Michael says:

    In fact, B (the precursor to C) was interpreted (sort of) and managed code. It was compiled to threaded code and executed by a interpreter (with a 2x memory hit and a 5x performance hit). See http://cm.bell-labs.com/cm/cs/who/dmr/hist.html for more information.

  11. BY Steve says:

    It seems that every C# application I write ends up needing some function from the Windows API that can’t be written in managed code. I end up creating a helper-project that builds an unmanaged dll in C++, then I use C calling conventions. Sure gets messy. I like the C# syntax, but it would sure make life a LOT easier if there was an Unmanaged C# compiler within Visual Studio.

Post a Comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>