Automatic memory management ... is it good or bad? There is no unequivocal answer and can not be. On the one hand, this is convenient, although it will not be possible to completely forget about memory. On the other hand, you have to pay for convenience.
JavaScript is exactly the case when memory management is performed automatically, however, the appearance of ArrayBuffer and SharedArrayBuffer changes the situation.
')
In order to understand exactly what ArrayBuffer and SharedArrayBuffer bring to JS development, why these objects appeared in the language, we suggest starting from the very beginning, namely, talking about memory management.
Memory and work with her
RAM can be represented as a set of boxes. Or as a bunch of mailboxes that are in offices, or as lockers in kindergarten, where children can store their belongings.
If someone needs to leave something for one of the children, he can put it in his locker.
Lockers, in one of which someone is going to put something
Near each of the boxes there is a number, which, when applied to RAM, is an address. This address is used if someone needs to be informed about the place where we left something for him.
All boxes are the same size and can store a certain amount of information. How much exactly - depends on the specific computer architecture. This size is called the size of the word memory. Usually this is something like 32 or 64 bits. For simplicity, we will use 8-bit words.
Block of eight cells
If you need to put, for example, the number 2, into one of these 8-bit cells, it is very easy to make it, since the numbers are easily converted into a
binary number system .
Decimal 2 is converted to binary 00000010, which is located in the memory cell.
What if a cell needs to put something that is not a number? For example - the Latin letter H?
In this case, we need to find a way to represent the letter as a number. In order to do this, the letter must somehow be encoded, for example, use the
UTF-8 encoding. Next, you need a way to convert a letter into a number, something like an encoder in the form of a ring. The letter, after conversion, can also be saved in an 8-bit cell.
The letter H is converted, using an encoder, into a decimal number 72, which, after being converted into a binary number system, is placed in a memory cell
When we need to get a letter from the cell, we need to skip the number that represents it through the decoder, so that instead of the number, we again have the letter H.
Automatic memory management
Programming in JavaScript, in fact, you can not think about what is happening with memory. This part of the system is abstracted from the developer. This means that it does not work directly with memory.
Instead, the JS engine acts as an intermediary. He is responsible for managing the memory.
A set of memory cells behind the fence, access to which is controlled by the JS engine
So, suppose a certain JS code, like the React library, wants to create a variable.
React asks JS engine to create a string variable
After receiving a request to create a variable and assigning it a value, the JS engine passes this value through the encoder to get its binary representation.
JS engine converts a string variable to its binary representation
Then the engine searches for a place in memory where it can place the resulting binary representation. This is called memory allocation.
JS engine looking for free space for binary data
After that, the engine watches whether the variable is available from any place in the program. If the variable is no longer available in the program, the unused memory must be returned for further use, after which the JS engine will be able to place new data in the released memory.
Garbage collector clears memory
The process of observing variables — strings, objects, and anything else stored in memory, and clearing memory after data stored in it cannot be accessed from a program — is called garbage collection.
Languages like JavaScript, in which programs cannot work directly with memory, are called languages with automatic memory management.
Automatic memory management can make life easier for developers. But it leads to an additional load on the system. Sometimes this load has an unpredictable performance impact.
Manual memory management
There are different languages that support manual memory management. For example, let's imagine how React would work if it were written in C (in fact, this is now
possible , thanks to
WebAssembly ).
In C, there is no level of abstraction separating memory management from a program that is found in JavaScript. Instead, the programmer works with memory directly, having the ability to load data from memory and store it in memory.
WebAssembly-version of React works directly with memory.
Compiling what is written in C or in other languages in WebAssembly, the tool used will add some auxiliary elements to the program code. For example, it could be a subsystem that deals with encoding and decoding bytes. This helper code is called the application runtime. In JavaScript, this role is played by the JS engine.
Character encoding tool added to .wasm file
However, for languages with manual memory management, the aids do not include garbage collection.
This does not mean that the task of managing the memory is entirely left to the programmer. Even in languages with manual memory management, the runtime usually provides some assistance in this matter. For example, in C, she watches which memory addresses are available by storing them in the free memory list.
The list of free memory reflects the current state of the system.
Here you can use the malloc function (its name is short for memory allocation, that is, memory allocation) to ask the runtime environment to find the addresses of memory blocks that are suitable for storing data. After memory allocation, the corresponding addresses will be removed from the free memory list. When stored data is no longer needed, it is time to use the free command to free up memory. Then the addresses of the freed blocks of memory will again fall into the list of free memory.
The programmer must decide for himself when exactly the aforementioned functions should be called. That is why what we are talking about is called "manual memory management."
It can be very difficult for a developer to decide when to clean various parts of the memory. Unsuccessful timing of the release of memory can cause errors or even cause security problems. If the memory is not released, sooner or later it will lead to the fact that it will be overflowed.
Results
In order to avoid human error, many modern languages use automatic memory management. However, with this approach, system performance and memory efficiency are affected. More on this next time.
Dear readers! In your opinion, what would change in JavaScript development if the language supported manual memory management without any auxiliary mechanisms like a garbage collector?