The idea of a process is perhaps the weakest part of the Library Analogy™. A process is when a set of instructions are performed by a processor. These set of instructions might output something to the screen or they might store information that was calculated. Processes are independent of each other, so one process should not be able to mess with the execution of another. One process can’t change another process’ instructions.
So let’s try and give it a Library Analogy™ counterpart. A process is the set of work that a student was given by their teacher. The students needs the help of the library assistant to do this work. The library assistant technically does the work for the student. The student is just along for the ride here. The work done by the library assistant is either stored in a notebook or it is said out loud. We have created a sweet library here, the work is done for you! You just have to show up at the right time! Also, the work for one student can’t mess with another student’s work. When a library assistant creates something for student A, student B can’t do anything about it, they have their own work to do.
Another weak link to the Library Analogy™ is the way that primary memory works. We made the correlation between primary memory and the shelves in the library. In a real library, if you put a book on a shelf, you will most likely find that book there the next day. In a computer, when you put something in primary memory, you will expect it to go away once the computer is turned off unless you saved it to the hard drive(secondary memory). So we have a weird library where books go away every night right after the library is closed. Only the books sent to the book repo will be available next time that we open the library.
To continue finding differences between real-life libraries and our Library Analogy™ library we move on to how processes use memory. We previously learned that processes use registers to store immediate information. Those registers are not big enough to hold all of the data that the process needs and they have to be shared with other processes while multitasking happens in the CPU. So we need a dedicated space in for our processes to be able to temporarily store data as operations are being formed. Think about any program you’ve written, there can be a number of variables whose data can change, networked content might be stored in Lists, and for something like a tree, huge amounts of data need to be processed.
Programs are allocated space on the shelves for all of their needs. This space is divided into four sections, the stack, the program instructions, the data section, and the heap.
The program instructions are just the written code that needs to be executed. This is akin to a student getting instructions from a teacher about what exactly needed to be done. These instructions will be placed in memory, somewhere on the shelves and they will be fetched one at a time.
These four sections must be placed in a consecutive manner within memory. It would be hard if a program’s stack on shelf 1, the instructions on shelf 1000 and the heap on shelf 6. It would take a long time to get things, when instead we can just be pretty quick if they are all of them next to each other.
The data section is used to store information that we know at the time of compilation. Things like static or final variables are stored here.
This is used for functional calls. For example if we create a function that has an array of size 100, the stack will “grow” to allocate space in RAM for that array of size 100. The stack also stores parameter values, function return addresses, and any local variables necessary. As soon as the function returns, all stack space for that function is cleared to be reused by another part of the process.
The stack has a fixed size, so that means you can end up overflowing the amount provided to you if you somehow have a huge amount of data from one function (like an infinite loop or infinite recursion).
To put this into comparison, imagine a student needing to do some work. They are given some spaces on a shelf, perhaps two rows. “As long as you are doing work in the library, these two rows are yours only. You may place any amount of written work here, as well as any books you might need for your work”. The student orders some books from the book repo, which might take a while to get here. Then, the student with the help of the library assistant writes a lot of stuff for one task. So much stuff that they fill up all of their given rows on the shelf. But they continue to write and overflow into someone else’s space. This is stack overflow.
The heaps is used for variables whose length or size we don’t know until the program is running. So in our previous example we knew we needed exactly 100 spaces in an array, but we no longer know that. Maybe we’re using an ArrayList and we have no idea how big it will get. In the heap, we are given some space and we need to manage that space ourselves (Java does the managing for us but other languages don’t). As we create new objects and add them to an ArrayList, those are stored in the heap part of our allocated shelf space.
The two rows given to the student must use up stack space, heap space, data and instruction space. So the heap grows from left to right while the stack may grow from right to left. The different between both is that the stack is cleaned up automatically, while we must take care of the heap tidying up ourselves.