Erlang/OTP: Rubbish Collector. “Reminiscence administration is like taking out… | by Viacheslav Katsuba | Erlang Battleground | Mar, 2023
“Reminiscence administration is like taking out the trash — it’s not glamorous, but it surely’s crucial for a clear and environment friendly system.”
Hello of us! Ukrainian Erlanger is right here ????! Within the present subject, I need to describe a bit of bit extra the Erlang Garbage Collector. Many builders lose sight of it or simply do not perceive it. That’s as a result of both they lack the time to analysis it or curiosity on this subject — in any case, that is fairly attention-grabbing and necessary for any sort of growth on Erlang/OTP. Hopefully, this text will show you how to develop and consolidate your information in regards to the Erlang Garbage Collector.
So, let’s rock ????!
The rubbish collector in Erlang/OTP is accountable for managing the reminiscence utilized by Erlang processes. It really works by robotically releasing up reminiscence that’s not wanted by the processes, which helps stop reminiscence leaks and ensures that the system makes use of reminiscence effectively.
One of many key options of the rubbish collector in Erlang/OTP is that it’s a generational rubbish collector. Which means it divides the heap into two generations: the youthful technology and the older technology. The youthful technology is the place newly allotted objects are saved, whereas the older technology is the place objects which have survived a number of rubbish assortment cycles are saved.
The younger technology is additional divided into two areas: the nursery and the minor heap. The nursery is the place newly allotted objects are initially saved. When the nursery fills up, the rubbish collector will carry out a minor rubbish assortment to establish and take away any unused objects. The surviving objects are then promoted to the minor heap.
The outdated technology is the place long-lived objects are saved. When the outdated technology fills up, the rubbish collector will carry out a serious rubbish assortment to establish and take away any unused objects. The most important rubbish assortment is a costlier operation than minor rubbish assortment and is thus carried out much less regularly.
Right here’s an instance for example how the rubbish collector works in Erlang/OTP:
-module(gc_example).
-export([main/0]).foremost() ->
spawn(enjoyable loop/0),
spawn(enjoyable loop/0),
timer:sleep(10000).
loop() ->
L = lists:seq(1, 100000),
io:format("Allotted record: ~p~n", [L]),
timer:sleep(1000),
loop().
On this instance, we spawn two processes that allocate a big record of integers and print them to the console. The timer:sleep/1
perform is used to maintain the processes operating for 10 seconds earlier than they terminate.
If we run this program utilizing the erl
command-line software, we will monitor the habits of the rubbish collector utilizing the erlang:reminiscence/0
perform. This is an instance of the output we’d see:
1> gc_example:foremost().
Allotted record: [1,2,3,...,99999,100000]
Allotted record: [1,2,3,...,99999,100000]
true
2> erlang:reminiscence().
[{total,4174696},
{processes,2935232},
{processes_used,2935112},
{system,1239464},
{atom,475057},
{atom_used,435142},
{binary,5208},
{code,2759580},
{ets,209832}]
On this output, we will see that the overall reminiscence utilization of the system is round 4MB. The processes
and processes_used
values point out the reminiscence utilized by the Erlang processes, which is round 2.9MB. The atom
and atom_used
values point out the reminiscence used to retailer atom names, which is round 475KB.
If we run this system for an extended time period, we will observe the habits of the rubbish collector. Right here’s an instance of the output we’d see after operating this system for a couple of minutes:
3> gc_example:foremost().
Allotted record: [1,2,3,...,99999,100000]
Allotted record: [1,2,3,...,99999,100000]
...
true
4> erlang:reminiscence().
[{total,4710904},
{processes,338179},
{processes_used,2823716},
{system,1329116},
{atom,473961},
{atom_used,435142},
{binary,5208},
{code,2766440},
{ets,209832}]
On this output, we will see that the overall reminiscence utilization of the system has elevated to round 4.7MB. It’s because the processes are repeatedly allocating giant lists of integers and printing them to the console.
If we wait just a few extra minutes, we will observe the habits of the rubbish collector because it frees up reminiscence that’s not wanted:
5> erlang:reminiscence().
[{total,4344544},
{processes,3093960},
{processes_used,140888},
{system,1250584},
{atom,473961},
{atom_used,435142},
{binary,5208},
{code,2766440},
{ets,209832}]
On this output, we will see that the overall reminiscence utilization of the system has decreased to round 4.3MB. The processes
worth signifies that the reminiscence utilized by the Erlang processes has decreased to round 3MB. It’s because the rubbish collector has recognized and eliminated any unused objects that have been beforehand allotted by the processes.
General, the rubbish collector in Erlang/OTP is a robust and environment friendly software for managing reminiscence in Erlang processes. By dividing the heap into two generations and utilizing a mixture of minor and main rubbish collections, the rubbish collector is ready to maintain reminiscence utilization low and stop reminiscence leaks in Erlang packages.
Along with the two-generational rubbish collector, Erlang/OTP additionally has a separate binary heap for managing reminiscence utilized by binary knowledge. Binary knowledge contains knowledge that’s represented as a sequence of bytes, equivalent to photos, audio information, and serialized knowledge. In Erlang, binary knowledge is saved in a particular knowledge construction referred to as a binary, which is a contiguous sequence of bytes.
The binary heap is used to handle the reminiscence utilized by binary knowledge in an analogous option to the rubbish collector used for different varieties of knowledge. When a binary is created, it’s initially allotted from the binary heap. When the binary is not wanted, its reminiscence is reclaimed by the binary heap.
Right here’s an instance of how the binary heap works in Erlang:
1> {Bin1, _} = binary:hex("0123456789abcdef").
{<<"0123456789abcdef">>,[]}2> {Bin2, _} = binary:hex("fedcba9876543210").
{<<"fedcba9876543210">>,[]}
3> erlang:reminiscence().
[{total,10483808},
{processes,4440960},
{processes_used,4413656},
{system,6042848},
{atom,46649},
{atom_used,43518},
{binary,21856},
{code,2357179},
{ets,308864}]
4> dimension(Bin1).
16
5> erlang:reminiscence().
[{total,10483808},
{processes,4440960},
{processes_used,4413656},
{system,6042848},
{atom,46649},
{atom_used,43518},
{binary,21872},
{code,2357179},
{ets,308864}]
6> dimension(Bin2).
16
7> erlang:reminiscence().
[{total,10483808},
{processes,4440960},
{processes_used,4413656},
{system,6042848},
{atom,46649},
{atom_used,43518},
{binary,21888},
{code,2357179},
{ets,308864}]
On this instance, we create two binaries Bin1
and Bin2
utilizing the binary:hex/1
perform. We then use erlang:reminiscence/0
to verify the reminiscence utilization earlier than and after creating every binary. We will see that the binary
worth within the reminiscence utilization tuple has elevated every time a binary is created, indicating that reminiscence has been allotted from the binary heap.
General, the binary heap in Erlang/OTP supplies an environment friendly and specialised manner of managing reminiscence utilized by binary knowledge, permitting for more practical reminiscence utilization and efficiency in Erlang packages.