I feel like I have to write something to break up the monotony of my sad story. So here’s some techno-babble to mix it up a bit. I have been working to improve memory usage by my new feed engine (which I’ve been working on for nearly two years, now). I found today that Perl has issues with reusing the same symbol for file handles… even in different scopes. I declared two methods in the same object. Both times, using the symbol FH to denote an open file handle:
sub AddEventLogText($$)
{
…
open(FH, “+>$fileName”) or die(“Could not open $fileName for writing.”);
$self->{EVENTS}->{$eventName} = \*FH;
…
}
sub RenderHTMLFile($+)
{
…
open(FH, “>ParseLog.htm”) or die(“Could not open ParseLog.htm for writing.”);
while(my ($event, $fileHandle) = each %{$self->{EVENTS}})
{
while( <$fileHandle> )
{
print FH;
}
}
…
}
So previously I had been storing event text in memory while my data was loading, but for some data suppliers the memory overhead became huge (750+MB). I decided instead to stream out the data to file and then read it back in when generating reports. I figured that I could use the symbol FH in two different scopes to represent two different file handles, but Perl did not see it that way
Despite opening a second file, I found that both my stored file handle and my newly opened file handle both had a globular reference to the same address in memory (0×2050858). So while I thought I was reading from one file and writing to a second, I was in fact, reading and writing to the same file (which made for some ugly reports). It only took me an hour or so what was going on
Argh!
So let that be a lesson! Never use the same file symbol twice! Either that, or use the Symbol module to generate anonymous globs (which I just read about).
Next thing to fix: circular object references. Perl garbage collection works by counting object references. I tend to use circular references to allow easy data/method access between objects, but that also short-circuits Perl’s garbage collection. Weak!