Hey hey :)
A few of us are trying to understand how const classes are instantiated and the impact that has on memory usage for an app.
const declarations in your app loaded into memory on App Startup?const Text('Foo') is created at runtime, but after that every const Text('Foo') just returns the same cached instance?const instances, then loading them into memory when they're first accessed?Are all of these questions wrong!? :P
Any help understand how const objects are instantiated and how that affects memory usage would be much appreciated :)
This sounds like it's Flutter related, so the VM-people are probably the best ones to answer the question in detail.
A few things are specified, though: If you use a <constObjectExpression> like const A(42) to obtain a constant instance of A, and its instance variables have values which are identical to the result _o_ of evaluating some other constant object expression (which could be the same syntax or some other expression which may or may not be textually identical), then the result must be _o_.
In other words, if we're going to create "the same value" then it must be the same object (which is the essence of canonicalization).
Similar rules apply to composite literals (lists, maps, sets) except that they are order-dependent (so it's not enough to be the same set, it must also have the same iteration order for its elements).
This implies that you will see some savings with respect to space (and, in practice, you won't actually create the new object and check that it's member-wise equal to an existing one, you'll decide already at compile-time or link-time that you must use that other one, so you will save some time, too).
This implies that you will see some savings with respect to space
Yep, definitely! I guess I was thinking of a larger app with a lot of const definitions. If those are all instantiated up front, that could slow down the "Time to first screen" in a Flutter app and take up memory.
If they're loaded into memory lazily then shared with all other instances that have the same properties (const A(42)), you'd definitely see a memory improvement over recreating that same object over and over, and would not suffer any consequences wrt "time to first screen."
If they're loaded lazily, then my question is: When do they get garbage collected? Like normal objects, or do they hang around until another potential usage?
@mraleph do you happen to have any insights here?
In AOT environment (Flutter release builds) all constant objects are evaluated and canonicalized at compile time, then serialized into snapshot. When you start your application the snapshot is loaded into memory and all constants come into existence. They are not loaded lazily. They are never garbage collected.
Hope this answers the question.
Excellent, thanks so much for the clear answer @mraleph :)
In AOT environment (Flutter release builds) all constant objects are evaluated and canonicalized at compile time, then serialized into snapshot. When you start your application the snapshot is loaded into memory and all constants come into existence. They are not loaded lazily. They are never garbage collected.
Hope this answers the question.
Have any performance problem if an app with too many const objects or const objects with heavy weight?
@tbm98 I could be wrong here, but I had the same question and was given this answer: In this case, they are loaded into "memory," but in AOT mode memory is an abstract concept. Memory does not always mean the data is loaded into RAM -- which was what I was thinking, not sure if that's where you're coming from as well.
Instead, the objects are loaded into something like an "Mmap," which as an abstraction layer over memory that "implements demand paging, because file contents are not read from disk directly and initially do not use physical RAM at all. The actual reads from disk are performed in a "lazy" manner, after a specific location is accessed. After the memory is no longer needed, it is important to munmap(2) the pointers to it." (Wikipedia).
So, from my understanding, const objects are loaded into memory -- not RAM, then read from the file system into RAM lazily when needed.
@mraleph or others, please correct me if I'm wrong in this assumption!
Most helpful comment
In AOT environment (Flutter release builds) all constant objects are evaluated and canonicalized at compile time, then serialized into snapshot. When you start your application the snapshot is loaded into memory and all constants come into existence. They are not loaded lazily. They are never garbage collected.
Hope this answers the question.