I am working on Blazor project, and I am using Virtualization component. I don't have any issue, but just trying to understand one thing.
I found that in Virtualization
component there is ItemsProvider
which returns ItemsProviderResult<TItem>
. It is Value type, but has a property Items
which is collection of reference types.
And here are my questions:
- If we lose a scope of
ItemsProviderResult<TItem>
will reference toItems
be left in memory or it will be removed? - How could I benchmark
Struct vs Class
performance differences in this particular case? - What do you think, why Blazor has done so?
I have googled general information about Value
and Reference
types. I found information about that struct is recommended to be always immutable. But I haven't found an answer for question what happens with Reference
type object if struct
loses scope.
UPD1:
I understand that the collection of reference type and any other reference type property will be released from memory by GC, but will it be at the same time when struct lose scope or it will be staying in memory until GC will remove it?
CodePudding user response:
If we lose a scope of
ItemsProviderResult<TItem>
will reference toItems
be left in memory or it will be removed?
In C#, if something goes out of scope it will eventually be released from memory.
So for Items
, it will become eligible for garbage collection when there are no more references to the struct that contains it or Items
itself. Items
will remain in memory until released by the garbage collector.
How could I benchmark
Struct vs Class
performance differences in this particular case?
You can make use of the Benchmark.NET library for testing methods that perform the desired operations using structs/classes.
What do you think, why Blazor has done so?
Items
will be a collection of whatever TItem
is.
If TItem
is a reference type, the you will have a collection of reference types.
If TItem
is a value type, the you will have a collection of value types.
CodePudding user response:
Value types will either be stored in the stack, or on the heap as part of an reference object [*]. Because of this value types are typically cheaper. If they are stored on the stack they will be handled automatically by the stack. If they are part on an object they will be collected as part of that object, the garbage collector does not need to do any extra work to keep track of it.
In contrast, reference types will always be stored on the heap. They will also need some extra memory for the GC to use for tracking and marking objects.
In some sense, value types is just a way to avoid listing multiple parameters. They might as well not exist at all as far as the garbage collector is concerned. A struct holding a reference going out of scope will be handled exactly the same as the reference itself going out of scope. I.e. the GC will collect the referenced object when it gets around to it. Assuming there are no other references.
In general, value types are preferred for small, immutable, types. While reference types are preferred for larger types, or if mutation of the value is needed. But whenever you think about performance, consider:
There is no doubt that the grail of efficiency leads to abuse. Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.
Yet we should not pass up our opportunities in that critical 3%.
I.e. it probably does not matter unless you have many thousands of objects.
Library authors need to be more careful, since they do not know how their library is used. And they cannot really change their mind if they realize they made a incorrect mistake, since that might break the code for thousands of users.
[*] Technically, stack/heap are implementation details.