Determining Allocated Memory in Delphi

November 4th, 2006

One of the new features of BDS 2006 is a new memory manager. As a result, all of the old ways to get the amount of allocated memory have been deprecated. It is surprising to me that they did not give you an alternative way to get this information, but thanks to some searching of the FastMM code, here is a method to get the amount of allocated memory for your process.

function AllocatedMemory: Cardinal;
var
  MemoryManagerState: TMemoryManagerState;
  SmallBlockState: TSmallBlockTypeState;
begin
  GetMemoryManagerState(MemoryManagerState);
  Result := 0;
  for SmallBlockState in MemoryManagerState.SmallBlockTypeStates do
    Inc(Result, SmallBlockState.AllocatedBlockCount * SmallBlockState.UseableBlockSize);
  Inc(Result, MemoryManagerState.TotalAllocatedMediumBlockSize);
  Inc(Result, MemoryManagerState.TotalAllocatedLargeBlockSize);
end;

Fixing the F-Lock Key

May 23rd, 2006

For some bizarre reason, Microsoft came up with this new idea on how to better use the function keys on their keyboards. Since most users never use them, why not make them have special meanings. F2 should undo, F3 should redo, F5 should open, etc. I am sure that there is at least one user out there that actually likes this behavior, but for those of us who use the function keys all the time, it is really annoying. I can’t count the number of times that I have pressed a function key, and suddenly I am staring at an open dialog instead of my browser refreshing. Fixing it is as simple as pressing the F-Lock key, but unfortunately this setting does not survive a reboot, or even a log out.

A couple of months ago, I looked around to see if I could find a way to disable the F-Lock key, but the only thing I found was a registry file that was supposed reverse the state of the F-Lock key so that it would be off by default. Installing that registry key caused my function keys to stop working entirely, so no luck there.

Today, I googled around a bit and found a much better workaround. There is an xml configuration file that contains information about what to do when a function key is pressed, simply cleaning out that file will remove the F-Lock feature, fixing your function keys for good. One thing worth noting is that it requires at least a log out before this fix will work.

Change of plans

January 26th, 2006

I was thinking of going to the Agile conference this year, but maybe I should go to the Waterfall conference instead.

Happy Birthday???

January 23rd, 2006

No wonder they were on clearance.

Impala-eating Rabbit

January 4th, 2006

This creature of legend is rumored to inhabit the great plains of North America. This rabbit is a close relative to the Rabbit with Big Pointy Teeth that inhabits the cave of Caerbannog. While very few of these rabbits have been spotted, they are rumored to have a taste for the wiring of Chevy Impalas. Stalking its prey for days on end, it strikes soon after the owner leaves the vehicle, but while the engine is still warm. It then enters the engine to strike at the heart of the Impala. After chewing on the wires for hours, it finally kills its prey, rendering it useless to its owner.

This creature has only been spotted a couple of times, but was never photographed until recently when one lucky individual was able to capture a grainy picture of it.

Not giving up its prize easily, the rabbit battled with the owner before finally realizing that even though it could take down a mighty Impala, it could not defeat this mighty human warrior. It escaped underneath the remains of its prey, and has not been sighted again.

Why can’t I just download the whole thing?

December 31st, 2005

At work they were selling a bunch of the old PC’s, and since my dad was wanting a laptop, I picked one up for him. One of reasons that they are selling the machines is that they have no networking capability (another long story). My dad picked up a Linksys PCMCIA card, and asked me to install it so he could connect to the network. This should be easy to do, right?

So, I stick in the cd to install the drivers, and get a prompt that you need IE 5.5 or greater to install their software. So I go up to the Microsoft site on another computer that has networking ability and download the IE 6 setup program. After copying it to the laptop, I fire up the install, and it says that it will need to download 13.9MB of files in order to install. That is not going to work with no internet access.

Being a technically savvy individual, I take a peek at the cd. There is a folder with the drivers in it, so I stick the network card in and install the driver. Now Windows detects the card, but there is way to select a network to connect to. Looking at the cd, there is also a utility folder with a setup.exe in it. Launch the setup program and now had the Linksys software installed. I fire up the software, and it says that it is searching for a network, but it never finds anything. This is not going very well so far.

Since my manual installation fails, I uninstall everything and start looking at trying to get an installation of IE 6 that does not require any downloading on the install computer. After a bit of googling I found this site. It seems that if you pass super special parameters to the installation, it will allow you to download all of the files that are needed. After copying all of these to the laptop, I install IE 6 successfully. I then run the official Linksys setup program, and everything works just fine.

If at first you don’t succeed…try another pair…or two…or the whole team

December 22nd, 2005

We have had a performance issue floating around at work where one operation was taking about 15-25 times longer than it did on previous versions. Obviously an issue that needed to be addressed. A couple of months ago, when we first identified the slowdown, we wrote a story card to find out how to speed it up.

Pair #1 picked up the card, and identified a way to speed it up some, and implemented their idea. Well, it was a little faster, but it broke a bunch of tests. They go back in and make a couple more changes. Now only a few tests fail. Since we had already spent more time than we should have trying to fix the tests, we decide to back out the changes, and have another pair take a look at it.

Pair #2 makes similar changes, but this time they don’t break the tests. It speeds up the operation a bit, but it is still far slower than it should be. At this point we write up a card to see if there are any other ways that we can speed it up.

Pair #3 finds that the we are not accessing the database in the most efficient way, and implement changes to reduce the inefficiency. The operation is faster, but still not fast enough.

Then comes this week when we have Don Roberts in as a consultant. We figured that since this is why we bring in highly paid consultants, we should let him take a look at it. Sam and Don picked up the card and ran a profile to see where the slowdown was. Initially, looking at the profile generated no new ideas. Digging a little deeper, we found that it was updating around 1/3rd of the records in a table, much more than we would have expected. Bringing in our resident expert Kim, we find out that most of the values it was saving were values that we calculate anyway. So we change it to only save the values that we need to be able to calculate the others, and about 99% of the updates disappear. Now the operation is much closer, and in some cases faster than it was in previous versions.

This one issue is really a testament to the value of pair programming and the agile process. If we all programmed in our own little cubes, we probably would have eventually found the issue, but it would have taken so much more time.

To STAThread or not to STAThread

November 2nd, 2005

About a month ago at work, we started running to a “Failed to load resources from resource file” error when minimizing one of our applications. After some googling, all we were able to find is that no one really knows what causes the error, but removing the STAThread attribute fixes the issue. We removed the attribute and it appeared to work just fine, but now when you try to open a save dialog from the program on Windows 2000, it just hangs. So now we can put the attribute back in and have it crash when it is minimized, or we can have it hang when you launch save dialogs on Windows 2000. Gotta love Microsoft.

Rubyish collections in C# 2.0

October 11th, 2005

In the limited amount of time that I have played around with Ruby, I have been impressed with how easy it makes a lot of things. Utilizing the power of blocks, it is this simple to print out the contents of an array.

    list.each {|item| puts item}

C# 2.0 gives you something similar to blocks with the new anonymous methods. Say you want to show a message when a button is clicked. Before 2.0 you had to do quite a bit of coding to implement the feature.

First, you have to implement your method.

    private void button1_click(object sender, EventArgs e)
    {
        MessageBox.ShowMessage("Hello, World!");
    }

Then you have to assign the method to the click event.

   button1.Click +=  new System.EventHandler(button1_click);

With anonymous methods, this task becomes much simpler.

    button1.Click += delegate { MessageBox.Show("Hello, World!"); };

Granted, if you had a decent designer, most of this would be done automatically, but you can still see how much easier stuff like this is in C# 2.0.

After looking at the examples for anonymous methods, it got me thinking about whether you could implement methods on a list class similar to the way Ruby does. So I started by making a delegate method, and a descendent of ArrayList.

    delegate void EachDelegate(Object item);

    class MyCoolList: ArrayList
    {
        public void Each(EachDelegate delegateMethod)
        {
            foreach (object obj in this)
                delegateMethod(obj);
        }
    }

Now, to print out the contents to the command line.

    MyCoolList list = new MyCoolList();
    list.Add("foo");
    list.Add("bar");
    list.Add("baz");
    list.Each((EachDelegate)delegate(object obj) { Console.WriteLine(obj.ToString()); });

The syntax is a little ugly, but at least all of the code is there in the same method. Now that I have a class that implements each, lets look at leveraging generics to make the class, well more generic.

First we need to make our delegate generic.

    public delegate void EachDelegate<ReallyCoolListElement>(ReallyCoolListElement element);

Then we make our list class descend from List<T> and use the new generic delegate in our Each method.

    class MyReallyCoolList<ReallyCoolListElement> : List<ReallyCoolListElement>
    {
        public void Each(EachDelegate<ReallyCoolListElement> delegateMethod)
        {
            foreach (ReallyCoolListElement obj in this)
                delegateMethod(obj);
        }
    }

To use this new class we can modify the original code to look like this.

    MyRealyCoolList<string> list = new MyReallyCoolList<string>();
    list.Add("foo");
    list.Add("bar");
    list.Add("baz");
    list.Each((EachDelegate<string>)delegate(string element) { Console.WriteLine(element); });

Or if you wanted to use it to sum up a list of ints.

    int sum = 0;
    MyRealyCoolList<int> list = new MyReallyCoolList<int>();
    list.Add(1);
    list.Add(2);
    list.Add(3);
    list.Each((EachDelegate<int>)delegate(int element) { sum += element; });

The syntax in C# is not nearly as nice and sugary as Ruby, but this does demonstrate some of the cool new features that are being added to C# 2.0.

Nano goodness

October 5th, 2005

I have to admit that Apple is really good at innovation and creating gadgets that just beg to be purchased. I have been able to resist them for the most part, but when the Nano came out, it was just to hard to restrain myself. The Nano was definitely worth the money, and it’s size is just awesome. The only drawback is its susceptibility to scratching. The front still looks great and you can only see the scratches if you are really looking for them. However, the scratches on the back are quite noticeable. Hopefully Apple will fix this with future Nano versions.