» » Garbage collection in Flutter

Garbage collection in Flutter

We do mobile development mainly on Flutter. In this article, let's talk about the algorithm that is used in any application - the garbage collector (Eng. Garbage collection). Its main task, as in any high-level programming language, is to watch for references and clean up memory areas in order to prevent memory overflow. Under the cut, we talk about how the garbage collection process works in Flutter - inactive and unused links, as well as local and global instances of the Dart language.

The Dart language uses a generational garbage collector. A garbage collector for short lifecycle instances, and a garbage collector for long lived instances that have survived more than one garbage collection cycle.

During the garbage collection process, the Dart Framework layer creates a communication channel with the Flutter Engine layer, through which it learns about the moments of application idle time and lack of user interaction. At these times, Framework Dart runs a memory optimization process to reduce the impact on user experience and application stability. In addition, rolling compression is used during application execution, which minimizes memory load by reducing memory fragmentation.

Young garbage picker

The young garbage collector algorithm performs the task of cleaning up objects with a short life cycle. This algorithm is similar in structure to the algorithm used in jаvascript. The main idea of ​​the young generation garbage collector is that not all objects in memory are processed, but only objects of the young generation. This type of collector is called much more frequently and is significantly faster than the older generation collector.

Work process

The amount of memory used can be conditionally divided into two half-spaces: one is always active, the other is inactive. New objects are located in the active part, where, as it fills up, live objects are transferred from the active memory area to the inactive one, ignoring dead objects. Then the inactive half becomes active - the process is cyclical.

 

To categorize objects as live or dead, the garbage collector parses the root objects of the stack and checks what they refer to. It should be noted that the Dart language does not use real pointers to objects, as it does in C / C ++, instead, the framework simply copies the references to instances. Live objects are objects to which there is a path by reference from the root object. Therefore, objects that do not have such a path are marked as dead. The collector then moves the live objects to an inactive memory area. The process continues until all objects matching the definition of living have been moved. The collector does not copy dead objects: in the future, dead objects will be overwritten with live ones.

Garbage collector “Parallel Marking and Concurrent Sweeping”

During the execution of the young garbage collector, memory is filled with "long-lived" objects. To process such objects, the “Parallel Marking and Concurrent Sweeping” algorithm is used.

 

The algorithm consists of stages: marking of living objects and removal of dead objects. At the first stage, the object tree is traversed, the used objects are marked with a special label. During the second stage, a second pass through the object tree takes place, during which the objects that were not marked in the first stage are processed. Then all marks are erased. The garbage collector locks memory objects for modification, hence the user interface. Locking is performed in order to avoid changing the statuses of objects in memory. After completing the procedure for marking objects, the application will resume work and start the process of cleaning dead objects. The labeling and cleaning process runs in parallel with the application.

How the garbage collector works in isolates

By default, a Dart program runs in a single isolate (thread), hence the garbage collector is the only one. When you create an additional isolate, a separate autonomous memory area is allocated, which has its own collector. The use of isolates allows you to offload the garbage collectors of the main isolate when working with high-load processes. This approach is a prime example of good practice in using the features of the Dart language.

Const & final

An integral attribute of the work of a Flutter developer is the use of the const and final keywords. The keywords const and final seem to have the same meaning, but they really don't. From a memory point of view, the key const means that not only the value is constant, but the instance itself, when using final, only the value of the instance is constant. Therefore, when using a final instance, a new area of ​​memory is allocated in memory, even if the value of the object is identical. When using a const variable, no new memory area is allocated, but a reference to an already existing instance is used. In this way, the garbage collector does not have to process many identical objects, the garbage collector only needs to check the state of references to this instance.

Conclusions

In the process of considering the garbage collection algorithm in Dart, one gets the impression that periodic memory locks only slow down the application, but this is not so. The life cycle of a Dart application is designed in such a way that garbage collection occurs during technical pauses in the Dart runtime. Given Flutter's ability to regulate its technical processes, the impact on user experience from the garbage collection process is kept to a minimum.

The developers of the Dart language did an excellent job of creating memory management tools, which resulted in a powerful garbage collection tool that provides high performance.

Related Articles

Add Your Comment

reload, if the code cannot be seen

All comments will be moderated before being published.