Archive for the '.NET' Category

In my previous post about GC.AddMemoryPressure Tomer Gabel commented that people should not use this feature since its not the correct thing to do.

In addition to that Yuval Ararat wrote a post about this issue as well.

First of all, if I wasn’t clear enough in my first post, they are technically write BUT (and there is a big but here) there are situations, mainly in interoperability issues that might require us to better notify the GC that behind this small and insignificant .NET object lies a whole lot of unmanaged memory that is allocated and will only be released when this .NET object dies.

Calling GC.AddMemoryPressure will simply make the GC consider this object for who it really is, a memory hungry object that hides behind it a lot of unmanaged allocated memory.

Originally I just wanted to introduce this feature to people and make sure they know about it even though its quite esoteric and will mostly be used by applications with specific needs (and believe me, I know at least one application that could have benefited from this feature if it was available in .NET 1.1).

And Tomer, regarding the typos and stuff, I usually try to spell check and proof my posts, but some times they slip by 😉

Maoni has a great post about the changes and improvments of the GC in CLR 2.0.
Read all about it. Its good stuff and its Important.

In addition to that, there is a link to the slides she used in her PDC lecture.

I’m hoping to write a few more tidbits about the new and improved GC in a future post, so stay tuned.

Enjoy!

This post is a bit futuristic, but since .NET 2.0 and Visual Studio 2005 release is very near, I thought I should start to talk about it a bit more.

.NET 2.0 will introduce an improved and better GC.
One of the parameters that the GC takes into account is the amount of memory a certain class instance takes. By doing so, the GC can better understand how much memory will be gained by collecting this object.

One of the inputs the GC takes into accoutn when decided whether to initiate a collection or not is the amoutn of managed memory allocated.
If we have a managed class instance that doesn’t allocate a lot of mamanged memory but holds a pointer to a large unmanaged memory (either a reference to a COM object that allocates a lot of information, or directly allocating unmanaged memory using functions such as Marshal.AllocHGlobal) the GC will not know about the unmanaged memory allocated and will not consider scheduling a GC sooner.

This means, that if there is no reference to that object and its finalizer releases the unmanaged memory, until there is a GC and the finalizer thread reaches that object, this unmanaged memory will not be released and may add pressure on the application’s memory usage.

For this purpose, in .NET 2.0 the “AddMemoryPressure” function was added to the GC class.

“AddMemoryPressure” allows the developer to notify the GC about the amount of additional unmanaged memory that was allocated in different places in the application. The GC will take this into account when considering the schedualing of a collection.

For example, if at some point in the application I create a COM object that I know allocates a bit chunk of memory, after creating it I will call “AddMemoryPressure” and give it a rough estimate of the amount of unmanaged memory this COM object takes.

For example:

class MySpecialBitmapClass
{
private long size;

MySpecialBitmapClass(string fileName)
{
size = new FileInfo(fileName).Length;
GC.AddMemoryPressure(size);
}

~MySpecialBitmapClass()
{
GC.RemoveMemoryPressure(size);
}
}

When I create the class I say that I will add a memory pressure which is at least as large as the file I’m working on. When the instance of this class is being finalized it will remove the pressure.

Be sure to tune in to hear some more changes and updates that are coming in .NET 2.0’s GC.

.NET allows creating Windows Services which are commonly used for unattended services such as Remoting containers.

For some reason, when using a Windows Services as a container for your Remoting application or as just a Windows Service that perfrom various tasks, the GC used is the workstation GC.

We have previously talked a bit about the difference between the workstation GC and the server GC but I’ll explain a bit about them again.

Workstation GC
The workstation GC is, as its name applies, is used in a workstation scenario. It is optimized for single CPU machines and for desktop application by using the main thread to perform the GC.
It uses 16mb segments that it reserves and sub allocates.

It has an option called “Concurrent GC” which allows the GC to run on a dedicated thread.

Server GC
The Server GC It is optimized for server operations and works only on a multi processor machines (CPUs that has Hyper Threading enabled are considered as two CPUs).

It has a GC heap per CPU and a thread per CPU that performs the garbage collection.
It uses 32Mb segments that it reserves and sub allocates.

All of these features make the Server GC more appropriate for demanding server applications due to its higher throughput.

Who uses the Server GC?
The only containers that use the Server GC by default are ASP.NET and COM+ (through Enterprise Services).

All other applications including Windows Services use the Workstation GC by default.

This means that even if you wrote a cool Windows Service in .NET that does cool stuff it may suffer from using a non optimized GC even though its a high throughput service that serves millions of users.

So, what can we do about it?
Before .NET Framework 1.1 SP1 you had to implement your own container for the CLR.
Since .NET Framework 1.1 SP1 you can just add to your app.config file the following tag and it will tell the GC to use the Server GC (of course, only if you have more than one CPU):

<configuration>
<runtime>
<gcserver enabled="true" />
</runtime>
</configuration>

You can read more about it (though not too much) in this Microsoft KB article.

For .NET Framework 1.0 you’ll still have to implement your own container for the CLR.
There are a bunch of these hangging around. A nice one is this one which is posted in The Code Project.


Just think about the fact that with one simple flag you can boost your Windows Service performance.

One of the strongest areas of .NET is interoping which allows .NET application to take advantage of legacy code whether it is written in the form of C DLLs or COM objects.

In this post I will talk about the Runtime Callable Wrapper (RCW) which is the .NET wrapper around COM objects when they are being accessed from .NET application.

Before we’ll discuss the internals of the RCW, we should first see how can we create it.

How can a .NET application access COM?
There are 3 methods a .NET application can access a COM object:

  1. Use the CreateObject function (only available in VB.NET)
  2. Add a reference to the COM object from Visual Studio .NET which will create an interop assembly automatically for you.
  3. Manually create an interop assembly and add a reference to it.

While option 2 and 3 are similar in result there are a few side effects on strong naming and namespaces which affects certain things. I will discuss about it later on.

How does an RCW object works?

The RCW is a .NET object which is a wrapper on top of a COM object. It is the bridge between the Garbage Collection approach of .NET and the reference counted approach of COM.

It is treated as a pure .NET garbage collected object which means it will be collected only when no one is referencing it.

Since there is no effective way of marrying the reference counted way and the garbage collected way what the RCW actaully does is always hold a reference of 1 to the COM object (excluding the cases where an RCW is marshalled across AppDomains, in which case its reference count is upped by one). This means that what will determine if the COM object lives or dies is the whether its RCW is alive (which in garbage collection words means its reachable from another .NET object or it is rooted).

An RCW also has a finalizer in which the COM object is actually being dereferenced and destroyed. This means that it takes at least 2 Garbage Collections until the COM object actually dies.

Important things we should all remember about RCWs:

Having an RCW control the death of underlying COM object means that instead of having the deterministic and immediate destruction model of referencing counting we have an undeterministic garbage collection and that is something we should keep an eye on.

The RCW itself is very light so having a lot of RCWs alive will not affect the size of the GC heaps too much, but it will affect the private bytes.

How to detect RCW “leaks”?

RCWs leaks are actually RCWs that are referenced and never released. While it is similar to finding leaking .NET objects that are still being referenced it has other impacts on the system.

As I said earlier, RCWs are light, this means the underlying COM object takes up memory in the default NT heap or in some other custom heap. If its not getting freed it adds presure on the Virtual Memory, since now the native memory takes up more and may take parts in the virtual memory instead of letting the GC reserve them.

Rembmer I said there are a few methods of adding COM objects to your .NET project? The main reason I listed them was due to the fact that each method of adding them to the project will make the objects appear a bit differently in WinDbg.

Option 1 – CreateObject – will make the RCWs appear of type System.__ComObject.

Option 2 – Adding a direct reference to the COM object – will make the RCWs appear as Interop.XXX.ComClassName where XXX is the name of the COM dll and ComClassName is the name of the COM class as it appears in the type library.

Option 3- Manually creating an Interop will make them appear like Option 2 if you did not change the namespace, or as the namespace that was chosen during the type library import using tlbimp.exe utility.

So, how can we actually detect them? There are two useful methods for that.

Using WinDbg to detect RCWs leaks

This method can work on a live debug or with memory dumps. The main technique is:

  1. Perfrom some operations that allocates RCWs.
  2. Take a memory snapshot or list all objects of that type that are currently alive.
  3. Run a GC
  4. Do step 2 again.

If you took memory dumps, all that is left now is to compare the list of object.

How to list the objects? Simply use !dumpheap -type XXX where XXX is the type of RCWs you use (see the 3 options above to see the names of RCWs object you can expect).

Using LeakDiag to detect RCWs leaks

LeakDiag is a tool developed in Microsoft to detect unmanaged memory leaks. It can track and give you the exact size of the unmanaged memory leak as well as the complete stack trace of the code that allocated that object.

Do use LeakDiag you need to attach it to a running process and perform the same technique as mentioned above with WinDbg. When you click on “Log” in LeakDiag you will be able to get an XML log file that will tell you the exact call stack of the leaking memory and you will be able to identify the call stack that leads to the exact COM object.

NOTE: Make sure you have the correct symbols for your COM objects and that you set up a correct symbols path to those symbols prior to attaching LeakDiag to the process.

You can download LeakDiag from here. Although this is not the latest version, it is still handy.

There is another handy utility (which is written in .NET) that parses the XML log files of LeakDiag called LDGrapher that you can use to view a little bit more easily the LeakDiag logs.

You can download LDGrapher from here (this is also not the latest version).

I plan to write in greater detail about LeakDiag and LDGrapher in a future post.

I’ll try and see if I can convine some of the guys at MS to release LeakDiag and LDGrapher like they released DebugDiag. I’ll keep you posted on those efforts here in this blog.

[UPDATE – 9:30AM]
[Added some of the links from Rico’s post and some more input on them]

This is a bit off topic, but I’d thought I’ll still give it a post since, as we all know, the best way to debug is to not debug at all. Avoiding common pitfalls and understanding how things work can save hours of debugging work at a later time.

Anyhow, I’ve stumbled upon a post by Rico Mariani in his blog about Whidbey Performance Opportunities.

(SIDE NOTE: his blog is full of interesting things since his current position is in the CLR performance team. If there is someone that knows how to squeeze extra performance from the CLR that’s him)

This post talks about some of the new things Whidbey (Visual Studio 2005) has to offer as well as the new .NET CLR 2.0.

The post offer links to each subject with additional information such as:

  • Review by Jason Zander of NGen – Its a little old but give a good insight as to what this tool does and how and when to use it. Keep in mind, as stated in the post, that NGen in v1.0 and v1.1 was mainly created for usage of the runtime itself. It got revamped a bit in Whidbey so that it is much better.
  • NGen is only good for a specific version of the CLR. If a new service pack was installed, there is a need to re-NGen your assemblies, otherwise their native image will be ignored and they will be considered as standard .NET assemblies that were not NGen’ed. As part of WinFX (which will be released in Windows codenamed Longhorn, now named Windows Vista) there is a new service called Native Image Service that does this tedious task of figuring out that certain assemblies needs to be re-NGen’ed and does that. You can use ceratin attributes in an assembly to give it better understanding of what to actually do with your assembly. You can read more about it here.
  • Another great post by Rico Mariani titled Six Questions About Generics and Performance.
  • An excellent two pieces post by Maoni about using GC Efficiently, Part1 and Part2.
  • Dodge Common Performance Pitfalls to Craft Speedy Applications using Reflection by Joel Pobar on this month’s (July) MSDN Magazine issue. It talks about imporvments of the reflection implementation in .NET 2.0 as well as the usage of some new APIs that lets you do things more quickly.Read, understand, let it sink in and by the time you’ll start working with it you’ll be better prepared.

Yesterday my RSS client, RSSBandit, decided to stop working.
Luckly RSSBandit is a .NET application with source code, so I’ve decided to start debugging it.
It kept on failing when it tried to deserialize one of its configuration classes from Xml using the XmlSerializer class.

The XmlSerializer class generates a temporary assembly in its constructor according to the XmlMapping it receives, compiles it and loads it.
Sometimes there is a problem at compile time. The code is not actually compiled and you will get a FileNotFoundException exception just for calling “new XmlSerializer(typeof(MyClass))“.

While trying to resolve this issue I’ve stumbled upon two tools that can help you better understand the cause of the problem and at some scenarios might suggest a resolution.

The first tools is a command line too called XmlSerializerPreCompiler written by Chris Sells. You just specify the full path to the assembly and the type name to check and it will try to create an XmlSerializer passing the type to it and analyzing the error.

The second one is a GUI tool that was based on XmlSerializerPreCompiler called XmlPreCompiler written by Mathew Nolton.

Both tools comes with full source code.

While I didn’t have time to check their source code I did see one of the things they use to get more information about the temporary assembly that is being compiled on the fly when creating the XmlSerializer.
It seems that there is a configuration flag that you put in the app.config file (if you don’t have one, just create one that is named myprogram.exe.config, where myprogram is your executeable name).

Just add the following to your app.config file:

<configuration>

<system.diagnostics>

<switches>

<add value=”4″ name=”XmlSerialization.Compilation”>

</switches>

</system.diagnostics>

</configuration>
This option tells the XmlSerializer not to delete the temporary files created to generate the temp assembly. It will leave the .cs file it was trying to compile, a .cmdline file which has the command line parameters that are sent to the compiler and a .out file which has the full command line that was used to compile the .cs file.

All of these files are generated it your %USERPROFILE%\Local Settings\Temp folder (which is usually equivalent to %TEMP%) and by just adding the above flag in your app.config you can get the input that is used in the programs I’ve mentioned above and investigate on your own.

While all of these programs couldn’t help me in resolving what is wrong with RSSBandit (and for that matter, any thing that has the “new XmlSerializer(typeof(MyClass))” code in it that runs on my machine) I’d thought it would be nice to share this information with everyone.

Since I don’t have time to further analyze this and I need my daily RSS feed dose, I did the following things:

  1. Ran WinDbg and started RSSBandit through it.
  2. Set a breakpoint (we have discussed about setting a managed breakpoint before) on System.CodeDom.Compiler.CompilerResults.get_CompiledAssembly (this function is the one that tries to load the temp compiled assembly and will throw the exception I’m getting in RSSBandit since the temp assembly wasn’t compiled).
  3. When the breakpoint hit (and it does so a few times until RSSBandit finishes loading) I ran !dumpheap -type CompilerResults
  4. I dumped the CompilerResults object using !dumpobject
  5. I then took the address of the pathToAssembly member and used !dumpobject on it as well.
  6. I then took the path, went there, opened the file named [strange random chars].out (where [strange random chars] is a unique name for each such assembly), opened it, copied the command line and ran it to generate the assembly.
  7. Continued doing this until we never reach the breakpoint again.

What I did learn from this workaround is that the main problem is executing the compiler command to compile the assembly and that will be the point from which I will continue to troubleshoot this issue.

At least for now RSSBandit is working (though only through WinDbg 😉 ) and I can read my favorite RSS feeds.

The Monitor class in .NET is a pure managed implementation of a Critical Section. It is used to synchronize multiple threads’ access to a code block.

C#’s lock statement and VB.NET’s SyncLock statement are actually evaluated into a Try..Finally block that has Monitor.Enter at the start and Monitor.Exit inside the Finally block.

For example:

[C#]
lock(myObject)
{
// Some code requiring synchronization
}

[VB.NET]
SyncLock MyObject
' Some code requiring synchronization
End SyncLock


The actual code produced is:

[C#]
Monitor.Enter(myObject);
try
{
// Some code requiring synchronization
}
finally
{
Monitor.Exit(myObject);
}

[VB.NET]
Monitor.Enter MyObject
Try
' Some code requiring synchronization
Finally
Monitor.Exit MyObject
End Try

There are two major issues that should be considered when using the Monitor class (or C#’s Lock and VB.NET’s SyncLock):

  1. Monitor only works on Reference objects and NOT value types. This means you cannot use an Integer as the object to lock when entering a monitor because it wil be boxed and releaed right away, effectivly not synchronizing the code.
  2. Locking should always be performed on private or internal objects.

There are a great deal of samples floating around that locks the “this” (“Me” in VB.NET) object, which means you are using the current instance as the object that is used for locking.

If this object is a public one and is used or can be used by others (either inside your organization or outside, if you work in an organization to begin with 😉 ), if you lock this instance and that instance is also available to someone else, they might also use it for locking and essentially create a potential deadlock.

So, what should we do about that?

ALWAYS USE PRIVATE OR INTERNAL OBJECTS FOR LOCKS!

The best way to avoid a deadlock is to ALWAYS use private object for locking.

For example:

[C#]
public class LockClass
{
private static object myLock = new Object()
public function void DoIt()
{
lock(myLock)
{
// Some code block that is in
// need of a sync
}
}
}

[VB.NET]
Public Class LockClass
Private Shared MyLock As Object = New Object()

Public Sub DoIt()
SyncLock MyLock
' Some code block that is in
' need of a sync
End SyncLock
End Sub
End Class

Remeber these two guidelines mentioned above and you will save yourself a lot of time trying to find an elusive managed deadlock that is usually hard to reproduce.

This is a bit off topic, but since I’ve already mentioned the Performance Monitor (perfmon) I’d thought I’ll address a behavior that some find intriguing.

When collecting performance information one must define a new counter log that will collect data from all relevant counters. When adding .NET counters to this log and openning the log file after running it for some time, sometimes you will see that it does not log .NET counters data and you will see them as if there is no data available on them.

This happens due to the credentials of the user running the performance monitor service.

So, how do we resolve it?

The solution is simple but is different between Windows 2000 and Windows XP/2003.

In Windows 2000, the only way of doing so is to change the user running the “Performance Logs and Alerts” service from the Services console.

In Windows XP and Windows 2003 a bit more thought was given to this issue and you can set the specific user that will run this counter log (its per counter log!).

To do so, just add the user at the “Run as” section and it will also question you for the password (as you can see by the screen shot below).

Hope this helps, Enjoy!

From day 1, .NET presented an easy to use ThreadPool that will handle all of your queuing/dispatching needs.

While ThreadPool is a cool thing that saves you a lot of time dealing with multi threaded issues, one must be careful when using it and understand how it works and who else is using it to avoid common pitfalls.

Who Uses the ThreadPool?

  • Any asynchronous delegate invocation (BeginInvoke/EndInvoke pattern)
  • HttpWebRequest uses it internally to queue and dispatch web requests.
  • WebRequest uses it to dispatch the request
  • Some timers (like System.Threading.Timer).
  • The end user that uses Thread Pool directly.

The Problem

Consider a situation in which you have one of the above filling up the Thread Pool with queued items. Each queue item was implemeneted in a way that also uses the ThreadPool (either directly or by an async invocation). We then reach to a point where the ThreadPool is full and all of its requests are blocking and waiting to get some work done using the ThreadPool.

Bang! You are deadlocked! You have circular dependency that code that runs inside a ThreadPool worker thread is blocking because it runs a code that also needs the ThreadPool, but the ThreadPool is already full and it is also waiting to get a worker Thread to run on to of it.

Reaching this situation is quite easy under high load since by default, the ThreadPool is set to have 25 threads per CPU (A Hyper Threaded CPU is considered as two CPUs by .NET and the Operating System and therefore a ThreadPool running on that CPU will have 50 threads, 25 per CPU).

The Solution

There is actually more than one way of avoiding this situation:

  • Query the ThreadPool using ThreadPool.GetAvailableThreads to see if you should queue the item or not. If you can’t, either throw an exception or wait until you can use it (just don’t wait if you are on a Thread Pool worker thread, i.e. you are running inside an ASP.NET page 😉 We are trying to avoid that). This is a similar approach that .NET takes internally.
  • Avoidance – Don’t call this code from within a place that uses the ThreadPool such as from within ASP.NET or from within an Async call.
  • Implement your own ThreadPool instead of using .NET’s ThreadPool – This is not as easy as it sounds, though.

There is an additional solution but its ONLY applicable in the coming .NET 2.0 which is to specifically call ThreadPool.SetMaxThreads. By doing so you will be able to increase the amount of threads available to the ThreadPool.

NOTE: Do mind that having too many threads per CPU is not recommended since the Operating System will spend a lot of time just making sure they are not starved.

As we can see, ThreadPool is a great thing that saves us the time and effort of implementing a multi threaded pool with all of its synchronization and other thread related issues but we still must understand that it has its limitation and we need to understand how it works and what it do to avoid unnecessary deadlocks and/or strange behavior.