Memory Footprint of GUI Toolkits

By Richard Szibele



While searching for the "perfect" GUI toolkit/library I've started measuring the memory usage of the various toolkits and I'm going to share my results here.

I basically wanted to answer the question: which GUI toolkit has the smallest memory footprint for a program with an empty window.

Disclaimer

This article provides an overview of the memory usages of various GUI toolkits, frameworks and libraries on Linux. All measurements were taken on the same Ubuntu 19.04 (Disco Dingo) x86_64 machine with the help of ksysguard, which gives us the private memory usage of the applications. I did not test the applications on a fresh Ubuntu installation, the installation which I tested them on already had development and other misc packages installed, which may or may not have affected/skewed the test results.

In a few cases I've even added some Windows 10 measurements into the mix, which one can't really compare to Linux memory usages, but they are clearly labeled as such.

These measurements are not scientific at all, and given a different setup you will more or less get different results.

Determining Memory Usage is not Trivial

What should we be measuring when comparing different GUI toolkits? virtual memory (VSZ)? resident set size (RSS)? private resident set size? shared resident set size?

The short answer: I believe private memory with smaps is a decent way to estimate memory usage of a process and is ideal when comparing two similar programs with different toolkits/libraries. ksysguard uses smaps in the detailed memory view.

However, I used the default memory view since the beginning and only later found out that smaps was a more accurate representation of memory usage. To keep the data consistent I continued to use the default memory view for all toolkits, though the data would likely show a similar trend when using the detailed view.

The long answer: ... is out of scope for this article, as I would have to explain Linux memory management and there are already great resources for that available: ELC: How much memory are applications really using?, The /proc Filesystem, proc - process information pseudo-filesystem, Linux Memory Management Overview, Memory Management

List of GUI Toolkits and their Memory Usage

Without further ado, here are the results:

GUI Toolkit priv. Mem. (MB) Notes xcb 0.132 xlib 0.156 nuklear (rawfb) 0.624 does not increase xorg memory xforms 0.765 WINAPI (Win10) 1.00 on Windows 10 dlib 1.10 SDL2 (without opengl) 1.10 GDK 1.20 turbo vision 1.30 TUI nana 1.40 Motif 1.50 FLTK 1.70 MSEGui 2.04 FOX 2.20 nuklear (x11) 2.20 0.4MB + 1.8MB xorg memory WINAPI (WINE) 2.30 LCL (customdrawn) 2.50 Gtk+2 2.80 wxX11 3.00 not production ready libui 4.00 LCL (Gtk) 4.50 Gtk+3 5.00 wxGtk3 6.00 EFL 7.20 GLFW 9.00 JUCE 10.00 projucer binary, not empty window Sciter 10.00 around 10MB, Linux Scapp missing LCUI 11.00 GLUI 12.50 SFML 13.20 nanogui 14.00 SDL 14.00 U++ 14.00 Agar 15.00 Dear ImGUI (SDL) 15.30 GuiLite 15.80 Dear ImGUI (SDL/Vulkan) 16.50 Mono WinForms 16.564 on Windows 10 Qt 17.00 Ultralight 20.00 revery 23.50 Java Swing 59.30 OpenJDK 12 electron 74.60 JavaFX 80.00 OpenJDK 12 horus_ui 94.00 Flutter Desktop 98.00 update: early development! Boost.UI - uses wxWidgets CEGUI - how does one build this :(? IUP - similar to wxWdigets, uses Gtk+ on Linux Lgi - uses Gtk+ 2 MiniGUI - build fails morda - build fails SFGUI - uses SFML TGUI - uses SFML Verdigris - uses Qt

I was surprised to find out that Flutter was such a memory hog, seeing that it was initially intended to be a GUI framework for mobile phones.

Update (thanks kirbyfan64sos): Flutter Desktop is still in early development and all builds are debug builds. This means that profile tools are active (e.g. Observatory), debug assertions are all enabled and the AoT (ahead of time) compiler is disabled. It will be interesting to see the memory usage once release binaries are available.

I can't say I was surprised to find Electron up there with the hogs.

HorusUI was interesting in that I expected it to use around ~20MB, as it uses OpenGL and is an immediate mode GUI. No idea why it uses so much.

The Java GUI frameworks Swing and JavaFX are also interesting, they are both pretty heavyweight and if you're not sure if you should use Swing or JavaFX for your new Java project then it seems like it would make sense to just accept the little bit of extra bloat and use JavaFX, which is a lot nicer to work with and more modern. Or maybe not if you don't like the extra memory bloat.

Qt is also at an interesting spot, it's heavier than most other mainstream toolkits. One thing that's interesting about it, is that a large chunk of the memory used is due to the amdgpu driver on my system. Perhaps OpenGL buffers being stored locally? The same thing can be seen with SDL2, where the program without OpenGL support uses 1.1MB and the one with uses 14MB.

WxWidgets and LCL held their ground in this comparison. Even though they are wrappers around other GUI toolkits, the overhead seems to be minimal at best. I really like the idea of being able to switch the underlying backend from Gtk+ to Qt for instance, thereby guaranteeing toolkit independence.

Nuklear gets a special mention, simply because I think it's a pretty awesome immediate mode GUI. If you don't mind using a raw X11 framebuffer, then you can get a window up on the screen with 0.624MB, which is pretty impressive.

Conclusion

If you were hoping for some kind of conclusion, then I'm going to have to disappoint you.