Linux Commands

Optimizing Linux Memory Usage

In part one of this series, we had a closer look at the Swap space, and part two dealt with tools and commands to manage the memory. Now, we will discuss various parameters and strategies to optimize the memory and its usage in general. This covers the amount of memory, the acceleration of the access, and the internal usage strategy.

Amount of memory

As already discussed in part one, the entire memory is called virtual memory, and consists of both physical memory and swap space. The availability of the physical memory depends on the hardware that is built into the machine as well as how much memory the processor can address, actually. As an example, 32bit operating systems have a limit of 4G of memory, only (2^32bit), whereas operating systems based on 64bit theoretically allow up to 16 EB (2^64bit).

To be precise the limitation is the motherboard with the processor itself, the memory modules that are supported by that motherboard, and the specific memory modules that are plugged into the memory slots on the motherboard. One way to maximize the available memory of the system is to use similar memory modules that have the largest size as possible. The second way is to use Swap memory as already explained in part one.

Access of memory

Next, an improvement of the access speed of the memory comes into consideration. At first, the physical limit is given by the memory module itself. You cannot go below the physical boundaries of the hardware. At second, a ramdisk, and at third the usage of zRAM can speedup the memory access. We will discuss these two technologies in further detail.

Creating a ramdisk

A ramdisk is a block of memory that the operating system handles like a physical device to store data on — a harddisk that is entirely kept in memory. This temporary device exists as soon as the system starts and enables the ramdisk, and the system either disables the ramdisk, or shuts down. Keep in mind that data you store on such a ramdisk is lost after the shutdown of the machine.

You can create a dynamic ramdisk via tmpfs file system, and via ramfs file system. Both technologies significantly differ from each other. First, dynamic means that memory for the ramdisk is allocated based on its usage (true for both methods). As long as you do not store data on it the size of the ramdisk is 0.

Creating a dynamic ramdisk via tmpfs is as follows:

# mkdir /media/ramdisk
# mount -t tmpfs none /media/ramdisk

Creating a dynamic ramdisk via ramfs is as follows:

# mkdir /media/ramdisk
# mount -t ramfs ramfs /media/ramdisk

Second, using tmpfs and unless explicitly specified the size of the ramdisk is limited to 50% of the physical memory. In contrast a ramdisk based on ramfs does not have such a limitation.

Creating a dynamic ramdisk via tmpfs with a relative size of 20% of physical memory is as follows:

# mkdir /media/ramdisk
# mount -t tmpfs -o size=20% none /media/ramdisk

Creating a dynamic ramdisk via tmpfs with a fixed size of 200M of physical memory is as follows:

# mkdir /media/ramdisk
# mount -t tmpfs -o size=200M none /media/ramdisk

Third, both methods handle swapping in a different way. In case the system reaches the memory limit of a ramdisk based on tmpfs, data from the ramdisk are swapped. This foils the idea of speedy access. On the other hand, the operating system prioritizes both the content and the requested memory pages of a ramdisk based on ramfs, keeps that in memory, and swaps remaining memory pages to disk.

In the examples above we have used /media/ramdisk as a mount point. Regarding regular data the only part of the Linux file system that is recommended to be used on a ramdisk is /tmp. This directory stores temporary data, only, that do not persist. Creating a permanent ramdisk that stores the /tmp file system requires an additional entry in the file /etc/fstab as follows (based on ramfs):

ramfs   /tmp     ramfs   defaults 0  0

The next time you boot your Linux system the ramdisk will be enabled, automatically.

Using zRAM

zRAM means Virtual Swap Compressed in RAM, and creates a compressed block device directly in the physical memory. zRAM comes into action (use) as soon as there are no more physical memory pages available on the system. Then, the Linux kernel tries to store pages as compressed data on the zRAM device.

Currently, there is no package available for Debian GNU/Linux but Ubuntu. It is named zram-config. Install the package, and setup a zRAM device simply by starting the according systemd service as follows:

# systemctrl start zram-config

As given by the output of swapon -s, the device is active as an additional Swap partition. Automatically, a size of 50% of the memory is allocated for zRAM (see figure 1). Currently, there is no way to specify a different value for zRAM to be allocated.

To see more details about the compressed swap partition use the command zramctl. Figure 2 shows the device name, the compression algorithm (LZO), the size of the swap partition, the size of the data on the disk and its compressed size as well as the number of compression streams (default value: 1).

Usage strategy

Next, we focus on the memory usage strategy. There are a few parameters to influence the behaviour of the memory usage and distribution. This includes the size of memory pages — on 64bit systems it is 4M. Next, the parameter swappiness plays a role. As already explained in part one this parameter controls the relative weight given to swapping out of runtime memory, as opposed to dropping memory pages from the system page cache. Also, we should not forget both caching and the memory page alignment.

Use programs that require less memory

Last but not least the usage of memory depends on the programs itself. Most of them are linked to the default C library (standard LibC). As a developer, to minimize your binary code consider using an alternative, and much smaller C library instead. For example, there are dietlibc [1], uClibc [2], and musl lib C [3]. The developer’s website of musl lib C contains an extensive comparison [4] regarding these libraries in terms of the smallest static C program possible, a feature comparison as well as the according build environments, and supported hardware architectures.

As a user you may not have to compile your programs. Consider looking for smaller programs and different frameworks that require less resources. As an example you may use the XFCE Desktop Environment instead of KDE or GNOME.

Conclusion

There exist quite a few options to change the usage of memory for the better. This ranges from Swap to compression based on zRAM as well as setting up a ramdisk or selecting a different framework.

Links and References

  • [1] dietlibc, https://www.fefe.de/dietlibc/
  • [2] uClibc, https://uclibc.org/
  • [3] musl lib C, http://www.musl-libc.org/
  • [4] comparison of C libraries, http://www.etalabs.net/compare_libcs.html

Linux Memory Management Series

Acknowledgements

The author would like to thank Axel Beckert and Gerold Rupprecht for their support while preparing this article.

About the author

Frank Hofmann

Frank Hofmann is an IT developer, trainer, and author and prefers to work from Berlin, Geneva and Cape Town. Co-author of the Debian Package Management Book available from dpmb.org.