Friday, June 23, 2006

Javascript garbage collection in Internet Explorer

I'm dealing with a memory leak in a DHTML application, in IE.

Supposedly, there's an undocumented CollectGarbage function in JScript:

Q Can someone point me to some good documentation for garbage collection in JScript? I need to find out how JScript cleans up.

A JScript uses a mark-and-sweep garbage collector with a variety of heuristics used to determine when to run garbage collection. The JScript garbage collector works like this:

1. When the script engine is shut down, garbage is collected.
2. When 256 variants, or more than 64KB of strings, or more than 4096 array slots have been allocated, the garbage collector sets a flag that says collect soon.
3. Whenever a new statement is executed or the script debugger starts, that flag is checked, and if it is set, a collection is done.

There is an undocumented JScript function called CollectGarbage that forces a garbage collection. This is for testing purposes only...


This article is from May 2001, so I wonder if it still applies. I'm calling CollectGarbage in my Javascript; no error occurs but I can't tell if it's doing anything. Hm.

Wednesday, June 14, 2006

Request-Tracker bug

I've finished installing Request-Tracker, a bug-tracking system, on a machine running Linux. Getting apache configured was a bit of a pain. When I finally got RT running under apache, I started getting the following message when I would restart apache:

No root path(s) specified at /usr/share/request-tracker3.4/libexec/webmux.pl line 112

To be clear, this error occurs while apache restarts. Apache-perl is running webmux.pl; it is included in the conf file.

I'm not the only one getting this problem; you can find this message using a Google search. But I couldn't find a reasonable explanation or solution.

Line 112 of webmux.pl looks like this:

rmtree([ bsd_glob("$RT::MasonDataDir/obj/*") ], 0, 1);

The command rmtree is used to remove files; bsd_glob is a command to expand a directory name containing a wildcard (among other things). So line 112 is just trying to remove all files and directories in the given directory.

I added some debugging code to print $RT::MasonDataDir and "$RT::MasonDataDir/obj" and the output of bsd_glob. Turns out that $RT::MasonDataDir is /var/cache/request-tracker3.4/mason_data. But the output of bsd_glob("$RT::MasonDataDir/obj/*") was empty - I got empty output from this debug line:

print bsd_glob("/var/cache/request-tracker3.4/mason_data/obj/*");


From this I surmised that rmtree does not like being passed the empty string, so I added a little workaround code, replacing line 112 with this:

my @adir = bsd_glob("$RT::MasonDataDir/obj/*");
if (@adir) {
   print "adir[0] is\n";
   print $adir[0];
   print "\n";
   rmtree([ @adir ], 0, 1);
} else {
   print "adir was empty\n";
}

(I'm not a great Perl programmer so I commented out the "rmtree" line while debugging.)

It turned out that if RT had been accessed via the web interface while apache was running, various directories and files would be created within that obj directory, and the first branch of the if statement would be taken; all non-hidden subdirectories and files of $RT::MasonDataDir/obj were removed (I checked).

Then if I restarted apache without using the RT web interface first, there were no new files or directories in the obj directory (I could see that). That's when the second branch of the if statement was taken. So now there are no errors; that's one problem solved.

Friday, June 09, 2006

Java-to-Javascript communication problem

I'm working on a Java applet that needs to stay in touch with Javascript objects in the web browser. In particular, the applet needs to grab elements from a Javascript array. It turns out that Java to Javascript communication can be done via the netscape.javascript package, which comes with the Java Plug-in for your browser.

I had everything worked out using the JSObject getSlot method. All went well in Firefox. But then, when I moved over to testing in Internet Explorer (version 6), I got the following error:

netscape.javascript.JSException: Unknown name

Groan. It appears that the getSlot method is returning this error. I created a very simple test applet and a simple web page with just a single Javascript object that has an array filled with three strings, something like this:

arr[0] = "element 1";
arr[1] = "element 2";
arr[2] = "element 3";

In the applet, the Javascript object and its array are extracted without any problem, using the getMember method. Displaying the array in the applet code, I get something like element 1,element 2,element 3 - so the toString method displays the array with commas between the elements. The array is there, correctly filled in. But calling arr.getSlot(int) in the applet causes the "Unknown name" exception to be thrown. I tried calling getSlot(0), getSlot(1), and getSlot(2) - they all throw that exception. So does setSlot. It's annoying, but I guess I'll have to create a workaround.