VB6 Application where STAThread. And that is the reason that Winforms applications are
by default STAThread. Using MTAThread causes problems with some ActiveX Controls.
However STAThread has a nasty implication
"inside a STA thread, the finalizer thread must reenter the STA thread in order to finalize the component.
If the STA is blocked and isn't pumping, the finalizer has to wait in line until it does"
This can then cause leaks of components affecting the memory use.
"To get around this issue, you have some options (from best to worst), e.g.:"
1) Create your components in an MTA. ... Unless you have an explicit reason to use an STA, you shouldn't. I realize that Visual Studio adds these to some entrypoints automatically for you.
For example, most GUI applications have to start life inside an STA, e.g. WinForms, but Console applications" or services "certainly do not."
"2) Deterministically release your resources. If you are using components which implement IDisposable, wrap them in
a C# 'using' statement or call Dispose() on them explicitly when you're done.
RCW's done have Dispose on them. You can consider doing a Marshal.ReleaseComObject on them directly,
but realize that this can cause problems if you're not really done using the COM object."
"3) Use another form of blocking to prevent the primary thread from exiting."
"Chris Brumme writes about this" (COM Apartments)
" at http://blogs.msdn.com/cbrumme/archive/2004/02/02/66219.aspx; caution: that's a fairly lengthy post"
Fixing memory leaks is sometimes hard. Because even if you track which is the instance
that is being retained, is difficult to determine WHERE was it created.
Another problem I have found difficult to tackle is when you get an exception because of
code that was put in a finalizer (yes I know that putting code in a Finalizer doesn’t sound like the
best programming practice but sometime I just have to give maintenance to code that does that).
So, my friend Jose de Jesus showed me a nice tip to identify where are those objects being created.
He told me to do the following:
1. Add an instance variable like:
public System.Diagnostics.StackTrace myClassStackTrace = new System.Diagnostics.StackTrace();
2. Just by doing that I can inspect that field and identify where was this particular instance created!.
JRockIt is an interesting Java Virtual Machine. I really admire the technology used in it. Well following Mike’s post about Memory Leaks in Coldfusion http://www.schierberl.com/cfblog/index.cfm/2006/10/12/ColdFusion_memoryLeak_profiler I was trying to configure the JRockit JVM to do some profiling on an important application.
But alas. Time just flies and things have change a lot since Mike wrote that post. So this is basically an update:
1) JRockit must be downloaded from: http://www.oracle.com/technology/software/products/jrockit/index.html You must accept the license and also have an OTN Account (this is a free process). Download the right version for your platform. I tried the x86 version on my 64 bit server and it didn;t work, so use the version that fits better to your platform. However there is no 64 bit client version of Memory Leak and all the other nice client tools. But dont worry. Download both version 64 and 32 bits versions. You will use the 64 version for your server and the 32 bit version for monitoring.
2) Stop coldfusion server
3) Modify the jvm.config file. In my case it was in: C:\ColdFusion8\runtime\bin\jvm.config
comment out old java.home and add a new line like:
In the java.args setting, remove parameter –Xbatch (dont know why, it just didnt work)
add a parameter like:
*In my case I also had to disable security in C:\Program files\Java\jrmc-3.1.0-1.6.0\jre\management\management.properties with a line like:
4) Re start coldfusion