My attempt to make a simple Linux cleanup utility
Tags: go, linux, programming
Published: 2023-01-11 12:44:46

## 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):

```bash
sync; echo 3 > /proc/sys/vm/drop_caches
```

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:

```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
}
```

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):

```bash
swapoff -a && swapon -a
```

Calling this command in Go:

```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
}
```

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):

```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
}
```

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](https://github.com/arcxevodov/clnr). 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!