Monday, November 30, 2009

Who is this OutOfMemory guy and why does he make my process crash when I have plenty of memory left?

coppy right from : http://blogs.msdn.com/tess/archive/2005/11/25/496898.aspx

To answer this question, there are a few concepts we need to discuss.

Working on a 32-bit system, you can address 4 GB of memory, out of this 2 GB is typically reserved to the Operating System and 2 GB are allowed for each user mode process, such as w3wp.exe (asp.net) for example. This memory is called virtual memory and the 2 GB’s are 2GB independently of how much RAM you have added to the system.  The amount of RAM simply decides how much paging and swapping you will do, i.e. how fast memory access will be.

When a process allocates memory it does so by first reserving virtual memory and then committing memory out of this chunk (this is the memory actually used). The committed memory is called private bytes.

The virtual address space is used for a number of different items in the process such as:

  • Dll’s
  • Native heaps (non .net heaps)
  • Threads (each thread reserves 1 MB for the stack)
  • .net heaps (for managed variables)
  • .net loader heap (for assemblies and related structures)
  • Virtual allocations made by com components
Virtual memory allocations are not necessarily (or very seldom) lined up nicely in memory. For example, dll’s have preferred loading addresses so gaps are left between them, and virtual allocations that have been de-allocated will also leave gaps.  This means that even though you can address 2 GB of virtual memory you may not be able to use it all since when enough memory is used, the memory will look somewhat like a Swiss cheese and your plug might have a big enough hole to fit in.

This is what happens when you get an OutOfMemory exception.

I will likely talk more about .net memory management later, but for now I’m going to make it very brief since there are several very good blogs about this such as Maoni's CLR Performance blog http://blogs.msdn.com/maoni/  and http://blogs.msdn.com/yunjin .

In the .net framework the garbage collector which is our memory manager reserves virtual memory in heaps. Once these heaps are created and we create a new instance of a .net object this object is stored in these heap segments and memory is committed.

In the .net framework 1.1 (server version) the regular .net heaps are created in 64 MB segments.  (variations occur if you have 8+ processors or have changed the settings manually but I will ignore this for now and talk about the common case)

These 64 MB segments need to be allocated in one big chunk, you can’t allocate 32 MB here and 32 MB there, so when you have filled up one of these 64 MB segments and a new segment needs to be created you will need to find an empty gap of 64 MB or more in the 2 GB memory space.  If such a gap does not exist you will get an out of memory exception. 

These OutOfMemory exceptions are generally not fatal but still bad as they leave the process in an unstable state.  However, when the garbage collector needs to do a collection it requires space for internal structures in order to do this collection, and the more memory and objects that you use, the bigger these structures are. If the garbage collector does not have enough space for its collections you will get a fatal out of memory exception and the process will die.

As you may have gathered from the above the reserved memory (virtual bytes in performance monitor) will be much larger than the committed bytes (private bytes in performance monitor). Usually the difference will be somewhere around 500 MB when memory usage is high, and at about 1.2-1.4 GB or so virtual bytes it starts getting very hard to find these 64 MB holes which means that a normal .net process will start getting OutOfMemory exceptions at around 800 MB.

Again, this value will differ depending on your application, the dll’s that are loaded and memory allocation patterns of native com components etc.

Now you know why you get OutOfMemory exceptions even though you have a lot of RAM, the next task is to find out why you are using this much memory and I will spend some time on that in future blog posts.

Wednesday, November 4, 2009

Optimizing C# String Performance

corpy right:
http://blogs.msdn.com/charlie/archive/2006/10/11/Optimizing-C_2300_-String-Performance.aspx

Optimizing C# String Performance

Strings in C# are highly optimized but also potentially very wasteful. They give programmers a safe, fast way to handle character data. However, there are a few tricks you need to know about strings and memory if you want to write efficient code. Without this information, you could easily write code that squanders both memory, and computer clock cycles.

Sharing Memory

To understand C# strings, you need to understand the answer to one fairly simple question. Suppose you have two string variables called MyString1 and MyString2. How can you get them both to point at the same place in memory? The goal here is not just to have two strings that contain the same value, but to have two string variables that reference a single block of memory that contains a string.
It turns out that the answer to this question is very simple and intuitive. The reasons behind the answer, however, are less obvious. Understand those reasons will give you the power to write code that is fast and efficient.
This post emerged from a thread on the C# forum. As often happens, I learned something in the course of the discussion. I've attempted to repackage that information and present it here in this post. The post begins with a look at Strings and StringBuilders, but the focus quickly switches to an exploration of how the String class handles memory.

Strings vs. StringBuilders

C# Strings are immutable. This means you can't modify an existing string. If you try to change it with the concatenation operator, or with the Replace, Insert, PadLeft, PadRight, or SubString methods then you end up with an entirely new string. You can't ever change an existing string. The operations you perform on a String frequently cause a new allocation of memory.
Allocations of memory are costly in terms of both memory and performance. As a result, there are times when you don't want to use the String class.
Developers who want to work with a single string and take it through an arbitrary number of changes in a loop can use the StringBuilder class. The StringBuilder class has many of the same methods as the String class. You can, however, change the contents of a StringBuilder class without having to allocate new memory. This means that in certain situations the StringBuilder class will be much faster than the String class. In other situations, however, the opposite will be true.
What's a developer to do? The String class is highly optimized and very efficient in most cases. However, if you need to modify a string then the String class tends to be a bit wasteful of resources. How concerned should developers be about this problem? How often should they abandon the String class and use StringBuilder? The answer, as it turns out, is "not very often."
You should only use the StringBuilder class if you need to modify a single string many times in a loop, or in a relatively small section of code. To fully understand why this is the case, you need to understand just how smart the String class can be when it comes to handling memory in typical programming scenarios.

What Makes a C# String Sharp?

The big win for Strings is the tricks they perform to limit unnecessary memory allocations. Look at this code:
   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Text;
   4:   
   5:  namespace CSharpConsoleApplication3
   6:  {
   7:      class Program
   8:      {
   9:          static void Main(string[] args)
  10:          {
  11:              String foo = "foo data";
  12:              String bar = foo;
  13:              Console.WriteLine(ReferenceEquals(foo, bar));
  14:              Console.WriteLine(foo.Equals(bar));
  15:              foo = "a";
  16:              Console.WriteLine(foo.Equals(bar));
  17:              Console.WriteLine(ReferenceEquals(foo, bar));
  18:              String goober1 = "foo";
  19:              String goober2 = "foo";
  20:              Console.WriteLine(ReferenceEquals(goober1, goober2));
  21:          }
  22:      }
  23:  }
The goal of getting two string variables to reference the same memory is achieved in lines 11 - 12. In this case, both foo and bar point at the same place in memory. To check, call the ReferenceEquals method (or the == operator). In this code, the call to Reference Equals returns True in line 13. We can also call the Equals method (line 14) of the String class to see that the two strings are equal in that they both have the same value. That is, they both point at the eight letters that spell "foo data".
Now change the value of foo, as we do in line 15. A C/C++ programmer might then expect that both foo and bar would still reference the same memory, and hence both have the value "a". This is not the case. Lines 16 and 17 both return False. The assignment of "a" to foo broke the connection between the two variables. Intuitively, this is what we would expect. It's only our "deeper understanding" of computer languages that make us see this as odd.
The final twist in this saga is that line 20 also returns True. Here we have assigned two different strings to two different variables. Our expectation is that these two variables should not point at the same place in memory. But line 20 shows that they do reference the same block of memory.
C# maintains something called an "intern table." This is a list of strings that are currently referenced. If a new string is created with code like that shown in lines 18 and 19, then the intern table is checked. If your string is already in there, then both variables will point at the same block of memory maintained by the intern table. The string is not duplicated. Again, this is intuitively what we want, but our understanding of computers makes us think that this is not what will happen. C# tries to conform to what we would intuitively expect to happen, not to what we think a computer is likely to do.
Some of the details of the intern table are discussed in this reference to the String Intern method.

Summary

This post explains a little bit about how C# handles memory allocations for the String class. Knowing this information is helpful if you want to write optimized code. It is also interesting information that intrigues us in part because it explains one small corner of the great wonder that is the C# language.
How important is it that one understands this information? That depends. For some people, it will be information they use every day. For others, it is just background noise. Writing safe, error free code is my most important task. Once that is accomplished, then I like to find time to work on optimization issues like those outlined here.

Optimizing C# Application

copry right from: http://www.vcskicks.com/optimize_csharp_code.html

Code optimization is an important aspect of writing an efficient C# application. The following tips will help you increase the speed and efficiency of your C# code and applications.

1. Knowing when to use StringBuilder

You must have heard before that a StringBuilder object is much faster at appending strings together than normal string types.
The thing is StringBuilder is faster mostly with big strings. This means if you have a loop that will add to a single string for many iterations then a StringBuilder class is definitely much faster than a string type.
However if you just want to append something to a string a single time then a StringBuilder class is overkill. A simple string type variable in this case improves on resources use and readability of the C# source code.
Simply choosing correctly between StringBuilder objects and string types you can optimize your code.

2. Comparing Non-Case-Sensitive Strings

In an application sometimes it is necessary to compare two string variables, ignoring the cases. The tempting and traditionally approach is to convert both strings to all lower case or all upper case and then compare them, like such:
str1.ToLower() == str2.ToLower()
However repetitively calling the function ToLower() is a bottleneck in performace. By instead using the built-in string.Compare() function you can increase the speed of your applications.
To check if two strings are equal ignoring case would look like this:
string.Compare(str1, str2, true) == 0 //Ignoring cases
The C# string.Compare function returns an integer that is equal to 0 when the two strings are equal.

3. Use string.Empty

This is not so much a performance improvement as it is a readability improvement, but it still counts as code optimization. Try to replace lines like:
if (str == "")
with:
if (str == string.Empty)
This is simply better programming practice and has no negative impact on performance.
Note, there is a popular practice that checking a string's length to be 0 is faster than comparing it to an empty string. While that might have been true once it is no longer a significant performance improvement. Instead stick with string.Empty.

4. Replace ArrayList with List<>

ArrayList are useful when storing multiple types of objects within the same list. However if you are keeping the same type of variables in one ArrayList, you can gain a performance boost by using List<> objects instead.
Take the following ArrayList:
ArrayList intList = new ArrayList();
intList.add(10);
return (int)intList[0] + 20;
Notice it only contains intergers. Using the List<> class is a lot better. To convert it to a typed List, only the variable types need to be changed:
List<int> intList = new List<int>();

intList.add(10)

return intList[0] + 20;
There is no need to cast types with List<>. The performance increase can be especially significant with primitive data types like integers.

5. Use && and || operators

When building if statements, simply make sure to use the double-and notation (&&) and/or the double-or notation (||), (in Visual Basic they are AndAlso and OrElse).
If statements that use & and | must check every part of the statement and then apply the "and" or "or". On the other hand, && and || go thourgh the statements one at a time and stop as soon as the condition has either been met or not met.
Executing less code is always a performace benefit but it also can avoid run-time errors, consider the following C# code:
if (object1 != null && object1.runMethod())
If object1 is null, with the && operator, object1.runMethod()will not execute. If the && operator is replaced with &, object1.runMethod() will run even if object1 is already known to be null, causing an exception.

6. Smart Try-Catch

Try-Catch statements are meant to catch exceptions that are beyond the programmers control, such as connecting to the web or a device for example. Using a try statement to keep code "simple" instead of using if statements to avoid error-prone calls makes code incredibly slower. Restructure your source code to require less try statements.

7. Replace Divisions

C# is relatively slow when it comes to division operations. One alternative is to replace divisions with a multiplication-shift operation to further optimize C#. The article explains in detail how to make the conversion.

Conclusion

As you can see these are very simple C# code optimizations and yet they can have a powerful impact on the performance of your application. To test out the optimizations, try out the free Optimizing Utility.

Profiling

An important concept when it comes to increasing the speed and efficiency of you C# code, is code profiling. A good profiler can not only let you know about the speed bottlenecks in your applications, but it can also help you with memory management. The best .Net profiler is probably RedGates ANTS Profiler. They have a free trial at their homepage you can download before purchasing the full product.

Optimizing the Downloading of Large Files in ASP.NET

Coppy right from:
http://blogs.objectsharp.com/cs/blogs/bruce/articles/1571.aspx

Maximizing performance is the holy grail of every web site. Developers are always looking for that edge…the way to squeeze more bytes of throughput from the same pipeline. Whether it be large files or small, download speed is of paramount importance. To facilitate a study of this topic, an examination of how to optimize the downloading of large files is useful, if only because even the smallest difference in speed is magnified if you’re trying to push 200MB files or larger to the client.

What are the Choices?

That, by the way, is the intent of this article. To describe the different choices that are available to move very large files from a web server to a browser client. As well as itemizing the choices, the article provides some empirical evidence showing the relative performance of each technique and discusses some of the reasons behind them. The choices that we are faced with are as follows:

· Allow direct access to the file

· Using Response.WriteFile

· Streaming the file using Response.BinaryWrite

· Use an ISAPI Filter

The next section looks at the mechanics of each of these choices.

Direct Access

The most obvious approach to delivering a file across the Internet is to place it in a directory accessible by a web server. Then anyone can use a browser to retrieve it. As easy as that sounds, there are a number of problems that make this alternative unworkable for all but the simplest of applications. What if, for example, you don’t want to make the file available to everyone? While adding NTFS-based security would protect the file from unwanted accessed, there is the administrative hassle of creating a local machine account for every user.

More flexible access control mechanisms run into similar problems. If you are using authentication schemes for which SQL Server or Oracle provide the data store, direct access is not going to be effective. There is no easy way to validate the credentials of an incoming request made through a browser against a database (without getting ASP.NET involved, that is). When all of these factors are taken into consideration, it becomes clear that direct access only works in very limited situations.

Response.WriteFile

Since direct access isn’t realistic, ASP.NET must be a part of the solution. Using the WriteFile method on the Response object is the simplest way to programmatically send a file to the client. The technique is quite simple. Create an .ASPX page or other HttpHandler to process the request. As part of the processing for the request, determine which file to download and use the Response.WriteFile method to send it to the client. The following is a simple .ASPX page that demonstrates this.

<%@ Page language="c#" AutoEventWireup="false" %>

<%@ Page language="c#" AutoEventWireup="false" %>

<%

if (Request.QueryString["File"] != null)

Response.WriteFile (Request.QueryString["File"]);

%>


Reffernce links: http://www.cnblogs.com/bestcomy/archive/2004/08/10/31950.aspx


One of the benefits of using Response.WriteFile is that the security for the request is much more extensible. The incoming requests are processed through the normal Internet Information Server (IIS) pipeline, which mean that IIS authentication can be applied to the request. And all of the events necessary to plug in your own custom authentication are available.

Aspnet_wp.exe

Request

aspnet_isapi.dll

AppDomain

Response

The Document

Named pipes

Inetinfo.exe


So what is the downside to using WriteFile? It does not work well when large files are involved. To understand why, a brief description of IIS’s architecture helps.

Figure 1 – IIS 5.0 Request Processing Architecture

Figure 1 illustrates the processes used in IIS 5.0. When a request arrives at the web server, Inetinfo.exe determines how it should be processed. For .aspx requests, the aspnet_isapi.dll handler is used. Aspnet_isapi.dll in turn communicates the request to the worker process (aspnet_wp.exe). The worker process contains one or more application domains (one per virtual directory, typically). The web site actually runs as an assembly loaded into the appropriate AppDomain within the worker process. It is this assembly that ultimately handles to the request, compiling and transmitting the response as necessary.

Going into a little more detail, aspnet_isapi.dll is a Win32 (i.e not managed code) DLL. The purpose of aspnet_isapi.dll is threefold. First, it is responsible for routing the incoming request to the worker process. Second, it monitors the health of worker process, killing aspnet_wp off if performance falls below a specified threshold. Finally, aspnet_isapi.dll is responsible for starting the worker process before passing along the first request after IIS has been reset. It is the first of these three tasks that is of interest to us.

The routing of the request as performed by aspnet_isapi.dll requires that a communication mechanism be established between it and the worker process. This is accomplished through a set of named pipes. A named pipe is a mechanism that, not surprisingly, works like a pipe. Data is pushed into one end of the pipe and retrieved from the other. For local, interprocess communications, pipes are the most efficient available technique.

Given this information, the flow of each .aspx request is: InetInfo.exe to aspnet_isapi.dll through a named pipe to the worker process. Once the request has been evaluated and a response formulated, that information is pushed back across the named pipe to aspnet_isapi.dll. Then back through Inetinfo.exe to the requestor.

If you put this architecture into the context of processing requests for large files, you can see why there might be a problem with performance. As the file is moved back through to pipe to aspnet_isapi.dll, it gets placed into memory. Once the entire file has been piped, the file is then transmitted to the requestor. Empirical evidence suggests almost a one-to-one growth in the memory consumed by inetinfo.exe (as shown by perfmon) and the size of the file being retrieved. Figure 2 contains the perfmon output for inetinfo.exe as two separate requests to retrieve a file 23MB in size is processed using Response.WriteFile.


Figure 2 – Memory Spikes in the Transfer of Large Files

Although there is no way to illustrate it here, this memory growth cannot be avoided. Even when buffering is turned off at every step along the way, starting from the ASP.NET page level and moving out to Response.Buffer = false. Sure the growth is temporary, but think of how much fun your server will have processing 3 or 4 simultaneous requests for 50 MB files. Or 30 or 40 requests. You get the picture.

Response.BinaryWrite and Response.OutputStream.Write

Given the memory growth that is the symptom of using the WriteFile method, the next logical step is to try to break the outgoing file into pieces. After all, if inetinfo.exe is placing the entire response into memory, then giving it smaller pieces should minimize the impact of transmitting a large file. Before the next piece comes in, the previous piece is sent on to the client, keeping the overall memory usage down. Fortunately, this is not a challenging problem, as the following code demonstrates.

using( Stream s = new FileStream( fileName, FileMode.Open,

FileAccess.Read, FileShare.Read, bufferSize ) )

{

byte[] buffer = new byte[bufferSize];

int count = 0;

int offset = 0;

while( (count = s.Read( buffer, offset, buffer.Length ) ) > 0 )

{

ctx.Response.OutputStream.Write( buffer, offset, count );

}

}

The code that adds the appropriate headers to the response have been left off for conciseness.

One of the benefits of this approach is that there is a lot more control that the developer can exert over the download process. Want to change the size of the buffer? No problem. Want to put a short pause between chunks in an attempt to give inetinfo.exe a chance to reclaim some memory? No sweat. Unfortunately, all of these scenarios are useless when it comes to large files. Regardless of the how the transmitted files are broken up or at which level buffering is enabled or disabled, large files end up becoming a large memory sink for the ASP.NET process.

ISAPI Filters

Given what has been discussed so far, it seems apparent that the problem with returning large file seems to be rooted in inetinfo.exe. More accurately, it seems to be found in the area surrounding where the named pipes are used to communicate between the aspnet_isapi.dll and the worker process. After all, when aspnet_isapi.dll isn’t involved (such as in the first scenario), there is no problem. For ASP.NET requests, large file transfers mean large memory consumption. So what can be done to reduce the amount of data that moves through the named pipe? What would be nice is if you could combine the speed of direct access with the authentication and authorization capabilities offered by .ASPX pages. Luckily, that combination is within our power to deliver.

The purpose of an ISAPI filter is suggested by its name. It is a DLL that sits between the requester and the web service. With an ISAPI filter, it is possible to intercept both ingoing and outgoing messages. As part of the interception process, the messages going in either direction can be modified. As well, because the filter is not an endpoint for a request, there is no need for the client to be aware that the filter is even being used. The term for this type of functionality is orthogonal, a fact that I mention only because it’s my favorite word.

So let’s consider what the purpose of this ISAPI filter is in the context of our dilemma. In the .ASPX page, we will take the name of the requested file and perform the necessary authentication and authorization. Then, as part of the process, the path to the requested file is placed into the headers that are part of the response. The response is then directed back towards the requestor. This is where the ISAPI filter kicks in.

The ISAPI filter in question interposes itself between the worker process and the requestor. It examines the outgoing message looking for a special header…one that contains a path to a file. When that header is detected, it extracts the file path, removes the header from the response and adds the contents of the file path to the response.

From the client side, the response now looks exactly like what is expected. From the server side, the request was authenticated and authorized properly. From the performance side, the file was streamed into the response as part of the inetinfo.exe process. Most importantly, it didn’t come through the named pipe that is used to communicate with the worker process. And the problem with the momentary memory growth goes away.

Comparing the Choices

As part of the investigation process, each of these alternatives was compared from a speed and a memory usage perspective. The results can be found in the table below

Download Technique

Download Speed (MB/s)

Download.ashx

5.89

WriteFileDownload.aspx

20.69

IsapiDownload.ashx

50.40

WriteFileDownload.aspx with IIS 6.0 Isolation

34.50

Table 1 – Relative Performance of the Different Techniques

Please realize that this is not a formal benchmark. A client application was created that transmitted a request to an appropriate configured server. The test was run 20 times for each technique, with an IIS Reset and a dummy request (used to spin up the IIS process) being performed before each of the tests. The numbers in the table represent the averages across all of the tests.

The More Things Change…

One of the challenges of working with technology is that the pace of change frequently causes old ideas to be tossed and new ones embraced. The introduction of IIS 6.0 had that effect on the architecture of ASP.NET. Although IIS 6.0 is capable of functioning using the same architecture (complete with an aspnet_isapi.dll and an aspnet_wp.exe worker process), there is a new model known as process isolation that impacts the solutions to the large download problem that we have been discussing. As before, a few words on the process isolation architecture are useful.


Figure 3 – IIS 6.0 Request Processing Architecture

When a request arrives at the web server, it is first processed by HTTP.sys, a kernel-mode listener. It is the responsibility of HTTP.sys to determine whether the request can be satisfied from the cache. If not, then the request is put into the request queue associated with the virtual directory that is the target of the request.

The actual servicing of the request is done by a worker process. The job of the process is to fulfill the request. The worker process listens on the appropriate request queue for the incoming requests (the ones placed there by HTTP.sys). The response is generated and sent back to HTTP.sys for transmission back to the original requestor.

Turning our attention back to the problem of large files, remember that the memory growth issue seemed to be rooted in the transfer of files into the InetInfo.exe process. Or specifically, the fact that Inetinto.exe seemed to hold the incoming file before sending it on to the browser. From the IIS 6.0 Isolation Mode model shown in Figure 3, you can see that the InetInfo.exe process is no longer part of the pipeline. As a result, when the request is run in this manner, memory growth is no long an issue. While transfer rate is not as fast as the ISAPI Filter technique (there are still a number of boundaries that need to be crossed), it is certainly an improvement over the same mechanism in IIS 5.0.

Summary

So there you have it. To serve up large files to a client, you can go with highest speed and most difficult security administration (direct access), slowest but simplest (Response object methods) or a combination of techniques (with a combination of pros and cons). Or you can improve on this last choice by upgrading to IIS 6.0 and running in Isolation mode. As always, there is no ‘best’ answer. All that I’ve done is provide you with the information necessary to make you own decision, whatever the situation.