AMSA

Week 5: Memory and Swap

Ferran Aran Domingo
Oriol Agost Batalla
Pablo Fraile Alonso

Goals for today

  • Any questions from the previous session?
  • Understand memory layout of a process
  • Understand Swap
  • Present and explain Prac-3.1

Recap

  • From zero to Linux
  • Linux concept of a: task (prac-2).
  • In the following three sessions we will see:
    • Memory
    • FileSystems

How does memory work on linux?

  • Each process have a Virtual Address Space.
  • Every Virtual Address Space have “more or less” the same “layout”.
  • The unit of the Virtual Address Space is a “page”.
  • Since every process has his own virtual address space, means that, two processes, can have the same virtual address pointing to a different page!

Virtual Address space layout

Layout

Text Segment

The code (binary) of the program, loaded to RAM.

Data Segment

That’s where global and static variables live, since they will live until the process dies.

// This goes to the data segment of the process VirtualSpace
int my_global_variable = 5;

int main() {
  // Main code here...
}

Stack

Every time we call a function, it pushes it contents to the stack. The variables initialized on this function also live inside his stack frame

void func_1() {
  float my_var = 0.0f;
}

int func_2() {
  int y = 1;
  int z = 1;
  return y + z;
}

int main() {
  int test = 0;
  func_1();
  test = func_2();
  test = 1;
}

Did we get it?

  • Really?
  • Sure?

Stack example, but now with pointers!

Pointers can be scary, but let’s see them in action!

void func_1(int *x) {
  *x = 1;
}

int func_2() {
  int y = 3;
  return y;
}

int main() {
  int x = 0;
  func_1(&x);
  x = func_2();
  exit(0);
}

The Heap

Heap

  • If we don’t know how large an array (or whatever data structure) needs to be, or if we need to store data across multiple stack frames, we can use the heap.

  • We can allocate memory in this region of the virtual address space and free it when it’s no longer needed.

  • Unlike the stack, the heap doesn’t have a fixed size limit (other than available system memory).

How to allocate memory from the heap

  • There are two syscalls brk/sbrk and mmap for allocating memory and unmmap / brk/sbrk for deallocating.

  • You’ll probably never use the syscalls, and use the glibc implementation called malloc and free.

Example of using Heap memory

void func_1(int *x) {
  *x = 1;
}

int func_2(int *y) {
  *y = 20;
}

int main() {
  int *var = malloc(sizeof(int));
  *var = 5;
  func_1(var);
  func_2(var);
  free(var);
  // Now the `var` virtual memory address is useless, since we
  // sayed that we want to `free` this memory.
}

What happens if my process allocates a lot of memory?

Possible solutions

  • Linux will first try to free up memory by flushing file-related caches (meaning it writes modified file data from RAM back to disk).

  • But what happens if most of the memory was allocated using malloc? In that case, there’s no corresponding file on the filesystem to write this data to! At this point, the system has two options:

    1. Kill the process: The Out-Of-Memory (OOM) killer from the kernel may terminate one or more processes to free up memory.

    2. Use swap space: The kernel can move memory pages to a swap partition or swap file. When a process later needs those pages, a page fault occurs, and the kernel retrieves the data from disk back into RAM.

Swap Partition vs Swap File

  • Swap partition is a partition on the disk that it’s occupied only for this cases.
NAME               MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
nvme0n1            259:0    0 476,9G  0 disk
├─nvme0n1p1        259:1    0   512M  0 part  /boot
├─nvme0n1p2        259:2    0     4G  0 part  [SWAP]
└─nvme0n1p3        259:3    0 472,4G  0 part
  └─crypted        254:0    0 472,4G  0 crypt
    └─root_vg-root 254:1    0 472,4G  0 lvm   /
  • Swap file: Create a file on your current filesystem.

How to create a swapfile.

  • You can create a swapfile with mkswap and activate it with swapon.

  • Create (do everything as root):

    # dd if=/dev/zero of={full_path_of_swapfile} bs=1MiB count=$((number_of_gb*1024))
    # chmod 0600 {full_path_of_swapfile}
    # mkswap {full_path_of_swapfile}
  • Enable (as root):

    # swapon {full_path_of_the_swapfile}
  • Disable it:

    # swapoff {full_path_of_the_swapfile}

    We have time?

    If you want to enable the swapfile every time your machine boots, you can add a systemd service that enables it

How to check if a swapfile is working.

  • See how much RAM memory do you have on your VM / PC with the free command.
  • Create a c program that:
    • Allocates (size_of_your_ram + some_arbitrary_number) with the malloc glibc function.
    • Use the allocated memory (you can use the memset function or a loop for assigning values) 1
  • Check with the free that swap is being used.

Quizz

Memory

  • What happens if I overflow the stack?
  • When working with multiple threads (SCP-related), what issues might arise if I pass a reference to a stack-allocated memory chunk?

Swap

  • What happens if I don’t have a swap partition/swapile and my memory is full?
  • What happens if my swap file is full?

References

Additional Exercices

If you really want to understand a little bit more what happens under the hood, you can do the following exercices. Be aware that you should read the “Really Recommended References” first, and then try to do this exercices.

We have time?

Observe how the output of the free command changes each time you run prac-3.1 with different swappiness values (e.g., 0 and 100). Then, create some plots to visualize the differences!

Activity 3

Ready to have some fun? Check out the third AMSA activity here!