Static vs. Dynamic Linking

by debianjoe

wuxpaper

Another Wuxmedia FBterm Shot

…nothing to do with this article, but it looks nice.

One of the factors in how most Unix-like operating systems work is that binaries are normally built using dynamically linked libraries.  For those who are unaware of what this means, it’s a standard for pulling in libraries for C/C++ that can either be linked on compile, or loaded and unloaded during execution.  The traditional naming for these is libfoobar.so.  They have a great deal of flexibility in how they can be used across multiple binaries, and since there is only a single lib being shared across perhaps multiple binaries, a significant amount of disk space can be saved.

Static linking involves creating libraries that are linked with, and thus become a part of, the code for the application.  If you take the time to read the IBM AIX documents, you’ll notice that they state “You can reduce the size of your programs by using dynamic linking, but there is usually a trade-off in performance. The shared library code is not present in the executable image on disk, but is kept in a separate library file. Shared code is loaded into memory once in the shared library segment and shared by all processes that reference it.”  The traditional naming for these is libfoobar.a.

I won’t go into the specifics of how to create the different types of libs, because if you’re writing libs, then you probably already know how to link them using compiler flags.

The question, and one that I’ve been wondering for a good while now is how substantial is the difference in speed if you converted the entire GNU / Linux core system to using statically linked libraries?  I’ve seen a few projects that took on this monumental task, but there has yet to be the kind of support I would have hoped to see.  Starch Linux is an interesting idea, but one that I’ve yet to check into.  I did notice that Sta-li looks to be in development, and since they’re already using many tools that I prefer in my own environment, I am looking highly towards the end product.

One of the other factors that I see as highly important in this endeavor, is movement towards using musl instead of the Glibc that we’ve all come to know far too well.  Musl is known for being far more simplified and smaller than the older GNU libs.  For a decent bit of reading, check out http://www.etalabs.net/compare_libcs.html to see a side-by-side comparison of the different libraries.  The great importance of this particular choice is that the individual statically linked binaries may actually not be significantly larger (or could possibly be smaller) than their dynamically linked counterparts.

Still, as a programmer, which should you use?  Once again, the IBM AIX documents have a really good suggestion.

One method of determining whether your application is sensitive to the shared-library approach is to recompile your executable program using the nonshared option.

If the performance is significantly better, you may want to consider trading off the other advantages of shared libraries for the performance gain. Be sure to measure performance in an authentic environment, however. A program that had been bound nonshared might run faster as a single instance in a lightly loaded machine. That same program, when used by a number of users simultaneously, might increase real memory usage enough to slow down the whole workload.

So, when it doubt…test it.

Advertisements