The more natural programming languages become, the fewer programmers are trying to get into something more advanced then programming patterns. They are intelligent enough to take care of all memory operations. The downside that any developer even does not want to know what’s going on there.
Around seven years ago, when I just started my programmer’s life, it was the first thing you should know to pass the interview. Not understanding memory construction could lead to significant issues in the project. Now it’s just one of many other topics that new developers are trying to avoid.
In this article, I will try to give you a basic understanding of memory, and explain why it is so simple — Will show what most of you didn’t saw before.
Before the start, I want to make a mark, that what will be told is a piece of general information about canonic memory structure and usage. Your programming languages may have differences. Also, to make this article easy for our minds, we will make some assumptions and avoid complicated details. Please do not throw eggs at me, in case information is not wholly accurate, it’s all for the pleasure of teaching process.
To better understand memory, let’s use humans canonic and most pleasured mind process – imagination. Imagine a big field graphed and divided into small square pieces with the same size.
This big field is our memory, where all objects are stored. Each little square is a minimum counted element of it named Byte. Yes, you heard me well, a byte is a minimum counted part in-memory representations, but we’ll get back to it later.
Let’s use your imagination a bit more. Part of this field is your area, where you can do anything you wish. Still, another part is a system related.
The system part is a part where additional information stored. It’s used to make all clandestine operations, store some metadata, and so on. With some precision, you can access it and make a mess there, but I’m not sure if it would be the best choice of your life.
So that’s how memory should look in your mind. Every-time you think about it, imagine this field with divided parts.
Let’s name a single divided field part – memory slot. It can be used for different size deviation, and the only thing this part should be consistent.
Getting back to the smallest counted memory object – Byte. Someone could think, “but the Bit is smaller than Byte, is he stupid?”. You are 100% right, I mean about a Bit, I’m not an idiot that would lie to you. Then why I told that?
Let’s get a bit of theory into this.
One Byte consists of 8 Bits. So Bit is smaller than a Byte.
Another thing that you need to know is that Bit can have only two values 1 or 0. The reason is quite apparent – Our “computer” has a hilarious amount of “lights.” Each light can have a signal passed or not. In physical meaning, our Bit in Memory is this singe Light in a computer system. If message passed, then Bit slot has 1 in it and light is On, if not then 0 and light is Off.
If 1 Byte = 8 bits and each Bit can have either 0 or 1, using combinatorics, we can calculate how many different values can be stored in it.
It can have two values in each available slot – 0 or 1, and there are eight of them.
? – it’s the operator that should be used.
Because rule between them is OR(First slot 1 OR 0, second can be 1 OR 0 …), we need to use multiplication.
2^8 = 256.
You can also get the same result by picking all values one by one, but it’s too painful.
Anyway, let’s get out of theory. Why then the Byte is the smallest memory slot and not a Bit.
It’s because minimum possible allocation(an object that can be stored in memory) has a 1-byte size, it’s char.
Wait a minute. What about Boolean?
It can have true or false, 0 or 1. It is an equivalent of a Bit, which means that Bit should be the smallest memory allocation slot.
And you would be right in an ideal world, but in a real one, boolean also takes 1 Byte, which means that one Bit there is used and seven else is trash — done it like that, to lower complexity of objects reading and writing into memory. More about it later.
Here is some fascinating history about Booleans in the past.
<At the beginning of the 2000th, we had a minimal amount of memory, especially if you were writing soft for some low memory devices. At that time, developers were forced to write a specific override that was telling “Boolean is 1 bit only”. It was waste development time and added overall complexity. With current device resources, it entirely affordable not to think about a few lost Bits, as it’s nothing in terms of total memory.>
Getting back on Reading and Writing complexity. At the 2000th, not only low memory resources were a problem, but also the speed of each operation.
And what do you think is the most used action in any app? Yes, it’s reading and writing into memory.
Even you do not see it, but anytime you create or edit a variable, you’re writing it values to memory. Anytime you want to check what is the value of a variable, you’re reading from memory.
Now, if we would tell our “memory reader,” read each Bit of an object and tell me what the value is? Or read each Byte of an object and tell me what the value is? The second one would be eight times faster, to ready an object with a size bigger than 1 byte. Comparing that boolean is not so widely used variable, it was decided affordable that losing 7 bits to make this operation faster.
In the end, the system is capable of reading each slot with a size of one byte. But does it?
The answer would be, “No.” Reading by a byte is also not the fastest solution for this operation. Comparing to objects that are mostly used in the apps and most optimal time saving per memory losses, the best decision would be 4 bytes. Remember this number, as in the next part related to Pointers you will understand why it’s so important and used.
The system goes and grabs four Bytes at one time.
The logical question should rise “What if I have a character in my slot and right next slot is four bytes – for example, the place where the Integer is stored? How will it work if the system grabs first four(one of character and 3 of Integer) and then grabs another four(1 of Integer and rest is a junk)?”.
With some precision promised at the beginning of the article, I can tell that when you create a character, even it has 1-byte size, it allocated the next 3 bytes as well, so Integer is stored only after them. In the end, this 3 bytes is never used ad system can have a step of 4 bytes per one read.
What does it mean for us? The real memory losses are much more significant, and when you’re creating a character, it may waste additional bytes, to make reading and writing operation faster. Now you know the truth, but there are even more significant memory losses that I will show in next part.
Keep in mind everything that looks hard is just something that needs better explanation. Hope what I wrote makes your life a bit easier & gives answers to why it’s essential to know memory structure. To understand memory – think like memory =)
In next article I will explain pointers, references, bit masks, stack & heap – simply all mechanisms that works with memory structure, and why they look like that.
To be continued!