A Practical Use Case of Page Swapping

Problem

Recently, I had to deploy a React project on a Linode server. What I didn't know was that the server only has 1GB of RAM. When I tried  npm run build I got the following error.

Allocation failed - JavaScript heap out of memory

Node's Memory Problem

Node is notorious for having a lot of poorly written modules. If the module's writer does not know how Node leverages memory, then the modules consume a lot of RAM. So what looks like a simple application can in fact hog up all the memory during build time.

A bit of Googling shows that Node allows V8's GC heap to be controlled with the --max-old-space-size flag. So I set the heap memory using node --max-old-space-size=4096 $(which npm) run build.  Sadly, I still got an out-of-memory error, so I ran sudo swapon --show to see what is the problem.

NAME     TYPE      SIZE   USED PRIO
/dev/sdb partition 512M 179.7M   -2

Turns out that I only have 512GB of extra swap space, so setting the max RAM size to 4GB does nothing at all.

Page Swapping

Fortunately, memory paging exists to deal with such issues. Memory paging retrieves blocks of memory called pages from secondary storage. The pages are then used as the main memory, which gives the illusion that the machine has more RAM.

First, I run sudo swapoff /dev/sdb to disable the the memory for paging.

I then run the following command to create the partition.

sudo dd if=/dev/zero of=/mnt/swap bs=1024 count=5242880

DD copies data from the /dev/zero file to /mnt/swap drive to be used as paged memory. Note that unlike /dev/null, /dev/zero can be used as a data source. bs specifies that the command writes in chunks of 1024 bytes at a time, for a total of 5242880 times. This effectively writes 5GB of data from the source to the destination.

Then, /mnt/swap needs to be set up as a swap area.

sudo mkswap /mnt/swap

Permissions for /mnt/swap need to be changed before using it as a page memory.

sudo chown root:root /mnt/swap

This changes the ownership of the /mnt/swap drive to the root user.

Finally, run sudo chmod 0600 /mnt/swap. This enables the drive to be read and written, but not executed. Ru ls -a /mnt/swap to verify that the changes have taken place.

-rw------- 1 root root 5368709120 Sep 22 16:08 /mnt/swap

Having done all that, sudo swapon --show gives me a 5GB of RAM to work with.

NAME      TYPE SIZE   USED PRIO
/mnt/swap file   5G 121.4M   -2

npm run build then proceeds smoothly.

File sizes after gzip:

  77 kB   build/static/js/main.be9bdc35.js
  7.1 kB  build/static/css/main.64e6a856.css

The build folder is ready to be deployed.

Permanent Swap File

The changes are only valid for the current session, so upon reboot the swap settings would not be retained. This behavior can be changed by adding the swap file to the /etc/fstab file.

fstab is the Linux's filesystem's configuration table that makes mounting and unmounting files easier. Adding a file into this table allows the file to be automatically mounted upon boot.

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Look within fstab to make sure that the changes have been applied.

# <file system> <mount point>   <type>  <options>       <dump>  <pass>
/dev/sda        /               ext4    errors=remount-ro 0     1
/dev/sdb        none            swap    sw                0     0
/mnt/swap       swap            swap    defaults          0     0

Summary

The post examined a problem that I encountered when trying to build a project on a server with limited RAM. By using page swapping, additional memory can act as the RAM, which allows the machine to perform tasks that it otherwise cannot. Instead of using a more powerful machine, the available resources on a machine should always be used to the fullest.



Comments (0)