After three years working on a C++ project, the executable has grown to 4 MB. I\'d like to see where all this space is going. Is there a tool that could report what the biggest
Don't just look at code - resources can easily cause multi-megabyte growth.
In Linux, you can use nm to show all symbols in the executable and to sort them in reverse order by size:
$ nm -CSr --size-sort <exe>
Options:
-C
demangles C++ names.-S
shows size of symbols.--size-sort
sorts symbols by size.-r
reverses the sort.If you want to get the results per namespace or per class, you can just grep
the output for 'namespace::
', 'namespace::class_name::
', etc..
If you only want to see symbols that are defined in the executable (not ones defined elsewhere, like in libraries) then add --defined-only
. Sorting by size should take care of this, though, since undefined symbols aren't going to have a size.
For Windows, you should still be able to use nm
on your binary files, since nm
supports COFF binaries. You can install nm
via cygwin, or you could copy your windows executable to a linux box and run nm
on it there.
You could also try dumpbin, which dumps info about a binary on Windows. You can get info on symbols with the /SYMBOLS
switch, but it doesn't look like it directly provides information about their size.
In Windows under Visual Studio compiles, this information is in your .map file (it'll be near the .pdb).
ADDED: To convert the decorated names found in the .map file to something more human-readable, you can use the undname.exe utility included with Visual Studio. It accepts individual names on the commandline or you can feed it a .map file.
For example,
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of "?push_back@?$mini_vector@U?$Point@U?$FixedPoint@$0O@H@Math@@@Math@@$05@@QAAXABU?$Point@U?$FixedPoint@$0O@H@Math@@@Math@@@Z" is
"public: void __cdecl mini_vector<struct Math::Point<struct Math::FixedPoint<14,int> >,6>::push_back(struct Math::Point<struct Math::FixedPoint<14,int> > const &)"
Get a link map, or use dumpbin
to get a list of symbols and sizes.
Chances are there's a lot of stuff being pulled in that you don't strictly need.
ADDED: Did you get a satisfactory answer? I realized there are two ways people approach problems like this:
Personally I prefer the latter - it gets results quicker.
You say the app is 4MB. Suppose the true necessary size is 1MB (or some such size). That means if you pick a routine at random from the map file, it is 75% likely to be something you don't need. Find out what's causing it to be included, and see if you really need it.
In the example you gave, you saw a class that wraps device-independent-bitmaps. You could find instances of that class in your app, and possibly replace them with basic WIN32 bitmaps. It would be less pretty, but save gobs of app size.
Then keep on doing it. Each large piece you get rid of makes the remaining pieces take a larger percentage of the app, because the app has shrunk but the pieces haven't. That makes them easier to find in the map file.
I could not get nm
to work for me but did manage to find a useful tool called Sizer. It reads the debug information created by Visual Studio using the Debug Interface Access libraries. It's pretty straightforward to use, as describe on the site.
Sizer.exe <path-to-exe-file>
. The output will go to stdout so you'll probably want to redirect to a file.The code sizes are broken down in different sections and grouped by function, data, class, etc, each section sorted in descending order of code size.