Ever wondered why your exe-File got so big after all the time you worked on it? Well, for that reason the map-file actually exists, but it’s not really easy to understand. Lines and lines of non-human-readable lines of debug text…
Wouldn’t it be great if there was a tool to parse it? That was at least what I was thinking. After searching and not finding anything the answer either was “There is not tool” or “You don’t know how to search”. Positively thinking it was the first I started making my own parser for map-files, so here’s the result of my short work to quickly find unnecessary units in my application.

DSMapParser

The tool (called DSMapParser) is quite simple in what it’s doing. You compile your project with a map file and open the map-file in the Map Parser.
The parser than (surprise!) parses the map-file and groups every file by its namespace. The result is a quite nice overview of all the units that bloat your application.

DSMapParser

Installation

  1. Grab the latest release from the github repository: https://github.com/delphi-sucks/DSMapParser/releases
  2. Extract it and use it! That simple!

Source: https://github.com/delphi-sucks/DSMapParser

Using it

Before you can actually use the map-parser you probably need to adjust some settings in your project to generate a map-file:

  1. Go to your project options: Project > Options
  2. Navigate to “Delphi-Compiler > Linking”
  3. Change the setting “Map-File” to “Segments”

Ensure that you have changed the options in your corresponding release-configuration.

After changing these settings your compiler creates beside your .exe-file also a .map-file, which can be used by the Map-Parser.

 

TL;DR

Parse your Map-File with the DSMapParser to find out why your application is so bloated.

The try-finally block is awesome. Especially for creating and freeing objects. But what do you all do when you want to create multiple objects in a row? Create a nested try-finally for ever object you create?

Object1 := TObject.Create;
try
  Object2 := TObject.Create;
  try
    ...
  finally
    FreeAndNil(Object2);
  end;
finally
  FreeAndNil(Object1);
end;

This is obviously quite an overhead when having multiple objects. So let’s create every object at the beginning and free all in the finally-block, right? Hypothetically asking for if it is right should already give you the hint that this is obviously wrong or rather even more bad.
For understanding purposes have an example:

Object1 := TObject.Create;
Object2 := TObject.Create;
try
  ...
finally
  FreeAndNil(Object2);
  FreeAndNil(Object1);
end;

At first this looks like a good idea. We have only one try-finally for as many objects we want to create, but here hides a possible memory leak.
Consider this; the first object got created successfully, but the second one raised an exception while creating. At this point we still are outside the try-finally-statement so we aren’t going to free the object that was previously successfully created.
Have this kind of bug a dozen times and you can say goodbye to your memory or even to your application because the memory ran out for it.

So lets just move the creation of the objects inside the try-finally! Well, that idea would be even more bad.
Variables aren’t initialized so we can assume that the objects point to some garbage. Now one of the objects can’t be created and an exception is raised, but the finally-block gets executed. That’s what we want! But then suddenly we get an access violation because of an object pointing to garbage…

And here comes the final necessary part for creating multiple objects with one try-finally. We just initialize it as nil, because the .Free method checks if the object is <> nil so we can execute this without worrying about errors.

Object1 := nil;
Object2 := nil;
try
  Object1 := TObject.Create;
  Object2 := TObject.Create;
  ...
finally
  FreeAndNil(Object2);
  FreeAndNil(Object1);
end;

With this method of writing one try-finally-statement for multiple objects you can have less overhead, because of no more nested try-finally-statements, and have a better overview of your objects.

Hint: Free the objects at reversed order to minimize bugs because of dependencies between the objects.

TL;DR

Use one try-finally for multiple objects by initializing every object with nil and creating them within the try-block.