Saturday, March 07, 2009

NGEN is Love, if you’re running your .Net applications via Citrix or Terminal Services

Mebyon Kernow - Developing .NET applications for deployment on Terminal Services or Citrix

“If you develop .NET client applications that are deployed to users over Terminal Services (TS) or Citrix then this is the post for you. Why? – well, there’s a bit of an issue that not a lot of people know about, and it can really ruin your day. First off some preamble about how we got here and why it’s an issue. I’ll then present a solution.

When a process runs on Windows it typically has some executable code and some data. To vastly simplify this let’s just say that the memory space taken up by my application includes different pages, some code - some data. There may well be other types of stuff in memory but that’s not important to this discussion at the moment. My application runs, loads up code into the pages allocated for code, and loads up data into the pages allocated for data. We’ll call these ‘Private’ memory pages.

Enter stage left: NGEN

You may never have found a use for NGEN (the Native Image Generator), and indeed you might not even know such a beast exists – so for those of you who don’t know, what NGEN does is pre-compile all of the IL into x86/x64 assembly language and stores the compiled image on disk to be used when needed.

The critical thing to understand about NGEN is that whilst it compiles your code, it also marks the code pages as shareable, so that multiple instances of your application can share parts of the memory space used by the first instance. And that’s really useful if you’re running under Terminal Services.

If you compare the first row from the shareable WS column you’ll see that the NGEN assembly has roughly 9Mb more shareable RAM than the original image. I know, 9Mb isn’t a huge amount, but it is a sizeable chunk if you run several users off the same box, and this was from one (admittedly large) .NET assembly. My app was about 3.5 Mb on disk – an application I’ve been working on from one of my customers is just over 40Mb as it includes a bunch of controls from 3rd parties and a whole host of other code.

Assuming I could get the same sort of benefit by running NGEN over my customers application then I might save 100Mb (!) per running instance. It doesn’t take a lot of users to make that significant – the 11th user would bring us to a saving of around 1Gb. Now we’re talking.

To Conclude

Hopefully this post has provided you with enough information to go out and grab some memory back on your TS/Citrix boxes. There’s another upside to running NGEN on your code – it’ll start up faster! This is because with a regular .NET application we have to JIT the code as we call it. With NGEN this has already been done, which generally means you get snappier application startup.

The ideas presented here are really only necessary when running your application under Terminal Services or Citrix. For regular client applications that’s unnecessary, but when running under TS/Citrix I’d say it’s not important, it’s imperative.

…”

If you’re using Citrix/TS as your deployment mechanism then you need to read the post in its entirety.

While my team doesn’t deploy via Citrix/TS there are a number of teams in our Practice that does, so I wanted to call out this post in the hope that it helps them and our clients…

No comments: