DEV Community

Cover image for My attempt to make a simple Linux cleanup utility
Artur Archevodov
Artur Archevodov

Posted on

My attempt to make a simple Linux cleanup utility

Introduction

Hello everyone! I am a novice developer in the Go language. Before that, I had, so to speak, a little experience, but in the form of a hobby. During the study, I also mastered Linux, now I use it as the main OS.

My laptop is quite weak, there is only 4GB of RAM on board, and on Windows there is a program that automatically cleans up RAM. After searching the Internet, I realized that there is no such utility that could quickly and easily clear RAM from garbage. Then I started trying to write it myself.

In this article I will tell you what I learned about RAM and what ways it can be cleaned.

A little bit about the RAM cache and an example on Go

After a little searching on the Internet, I found information about the cache that accumulates in RAM. There are two types of them in total:

PageCache is the place where the kernel puts the data that we wrote/read from the disk.

inode/dentrie the structure of the file system, the location of files and folders are recorded here.

To clear them, it is enough to enter one command (from the superuser):

sync; echo 3 > /proc/sys/vm/drop_caches
Enter fullscreen mode Exit fullscreen mode

Let's consider what this means:

sync - synchronizes data on disk with data in RAM

Writing the number 3 to /proc/sys/vm/drop_caches is a signal to the OS kernel that it is necessary to clear PageCache, inode and dentry

Here is how the execution of this command may look like in Go:

import (
    "os"
    "os/exec"
)

func cleanRamCache() error {
    err := exec.Command("sync").Run()
    if err != nil {
      return err
    }
    err = os.WriteFile("/proc/sys/vm/drop_caches", []byte("3"), 0)
    if err != nil {
      return err
    }
    return nil
}
Enter fullscreen mode Exit fullscreen mode

In this function, we executed the sync command, and also gave the Linux kernel a signal that it needed to free the cache by writing the number 3 to the /proc/sys/vm/drop_caches file.

Reloading the Swap file

Next, we can improve performance by moving data from Swap to RAM. To do this, use this command (also from the superuser):

swapoff -a && swapon -a
Enter fullscreen mode Exit fullscreen mode

Calling this command in Go:

import "os/exec"

func restartSwap() error {
    cmd := "swapoff -a && swapon -a"
    err := exec.Command("bash", "-c", cmd).Run()
    if err != nil {
      return err
    }
    return nil
}
Enter fullscreen mode Exit fullscreen mode

But it is worth considering that this action will increase the consumption of RAM, since all data from Swap is moved to it.

Getting information about RAM

I also wanted to implement information about RAM in the utility. To do this, I used cgo (Calling C functions from Go):

// #include <unistd.h>
import "C"

import "fmt"

func getRam() (string, string) {
    bTotal := C.sysconf(C._SC_PHYS_PAGES) * C.sysconf(C._SC_PAGE_SIZE)
    gbTotal := float64(bTotal) / 1024 / 1024 / 1024
    fmtTotal := fmt.Sprintf("Total: %.1f GB", gbTotal)

    bFree := C.sysconf(C._SC_AVPHYS_PAGES) * C.sysconf(C._SC_PAGE_SIZE)
    gbFree := float64(bFree) / 1024 / 1024 / 1024
    fmtFree := fmt.Sprintf("Free: %.1f GB", gbFree)

    return fmtTotal, fmtFree
}
Enter fullscreen mode Exit fullscreen mode

Let's consider what this function does:

Obtains information about the amount of RAM in bytes using the sysconf function with the _SC_PHYS_PAGES argument (the number of pages of physical memory), converts it to gigabytes and writes formatted information to fmtTotal

Does the same to get the available RAM (_SC_AVPHYS_PAGES)

Returns two string variables with information about the amount of RAM and available memory at the moment

And why is it necessary at all?

This utility would be useful for people who have not yet mastered Linux, and are used to programs such as Mem Reduct in Windows. Yes, this is only a small part of what can be implemented in this program. But I have already expanded the functionality of the program a little, adding flags, additional checks and even localization. The full code of the utility can be viewed in my repository. I will be only glad of your ideas on expanding the functionality of the utility. If you liked this article, in the next one I can describe other parts of the program's functionality, as well as a way to automate cleaning. Have a nice day!

Top comments (2)

Collapse
 
flchs profile image
François Lachèse

"mastered linux" 😶
I think the kernel memory management is quite complex and already well optimised.
You probably don't need to override the rock solid stock behavior, if your computer is struggling you will have better luck reducing ram hungry programs like chrome for example, or switching from a heavy DE like GNOME to a lighter one like XFCE or i3 if tilling is your thing. Or simply adding more ram, or a SSD if you don't already have one.

And writing a command that just run another command without adding anything, well...

Collapse
 
arcxevodov profile image
Artur Archevodov

"mastered linux" 😶

idiotic google translate, sorry for the slightly incorrect translation, I meant "started to learn linux"

I think the kernel memory management is quite complex and already well optimised.
You probably don't need to override the rock solid stock behavior, if your computer is struggling you will have better luck reducing ram hungry programs like chrome for example, or switching from a heavy DE like GNOME to a lighter one like XFCE or i3 if tilling is your thing. Or simply adding more ram, or a SSD if you don't already have one.

maybe you are right, that's why the article is called "my attempt to make ..."

And writing a command that just run another command without adding anything, well...

Well, one short command executes several large commands at once, and this is only the smallest that could be implemented in this program

Have a nice day!)