Thursday, April 17, 2008

COM Objects are not destroyed when using Server.CreateObject in Classic ASP (Jscript)

Recently it was discovered that, on a particular ASP page in our application, COM objects that were being created using Server.CreateObject were not being properly destroyed. Actually, I should rephrase that, they weren't being destroyed at all until the component services package was shut down. If I kept task manager open, and watched the mem usage of dllhost.exe, I could see the memory being used by the processed increased each time I hit the page in question, and never decreased. Also, if I went to Administrative Tools -> Component Services and looked at the Objects, Activated, and In Call columns for the COM objects in my package, I could see those numbers ever increasing without decreasing.

The code is written in JScript and looked something like this:
var o = Server.CreateObject("dllname");

/* do stuff... */

o = null; //<--- I thought that this line should cause this object to be destroyed, I was //wrong
After much searching I came across this article: PRB: COM Objects Created in JScript Not Released Immediately. The article basically says that because JScript uses deferred garbage (for performance reasons), it can sometimes delay object destruction (in my case, permanently delay it). The article offers two solutions, the first suggest that a destructor be written for the dll, and the second suggests that the undocumented CollectGarbage() function be used. I chose the latter, simply because adding to the dll would be a bigger inconvenience (aka laziness).

A third suggestion that I would suggest, just based on conjecture from information provided in the article, is to rewrite the code block causing the problem in vbscript, as it is not effected by this problem (no garbage collection).

As for my problem, I'm not entirely sure why the problem occurs on only one page and not the others. My only guess is that on the page that is having a problem all of the COM objects are instantiated (about 14), whereas on most others only one or two objects are created.

The following is my code, after I fixed it:
var o = Server.CreateObject("dllname");

/* do stuff... */

o = null;

CollectGarbage(); // <-- This one little line fixed my problem

Wednesday, April 9, 2008

Opening Component Services In Windows Vista

I really don't hate microsoft, or Windows Vista, for that matter, but I do hate it when they move things around and don't tell you where they put them. To get to component services in Vista you should do the following.
1. Open "Run," I usually do this by typing "run" in the dynamic search embedded in the start menu.

2. Type "comexp.msc" in the run window, and then hit enter.

Alternative:
Go to "%windir%\system32\comexp.msc" and click it, or make a shortcut to it and put it in administrative tools so it can be with all it's XP buddies.
And that's that.



Cause a SQL Statement to Wait (Sleep, Pause)

At work I was trying to simulate a query that took a long time to execute, in order to debug a problem that I was tasked to fix. My goal was to write it in such a way that I knew exactly how long it was going to take every time. That's when I came across code that would allow to do exactly that:
WAITFOR DELAY '000:00:20';
SELECT column_list FROM table_name;
This code will wait for 20 seconds and then and then run the code that follows it, which is exactly what I was looking for.