4 ms·
I'm no expert, so take my answers with a grain of salt. > Why can the constructor not allocate memory "progressively" for the object as the construction chain
by aw1621107 7y ago
I'm no expert, so take my answers with a grain of salt.
> Why can the constructor not allocate memory "progressively" for the object as the construction chain descends the class hierarchy?
I think it's a matter of allocating everything up-front being easier than the alternative. Even with a single-task OS/kernel and a single-threaded program, memory fragmentation could mean that a chunk of memory that is large enough to start construction wouldn't be large enough to finish it. As you mentioned, the OS/kernel could move the object under construction to a new chunk of memory, but there's no guarantee that the new chunk would be large enough, and performing said move is extra work that is relatively easy to avoid in the first place.
> Sub-question - why does the memory for an object need to be contiguous?
I think it has to do with a combination of predictability and efficiency more than it being technically infeasible.
The predictability side is probably most important for systems programmers, who are also the ones who need to worry the most about allocation behavior. For them, control over object layout in memory can be important, and the choice between using "normal" members instead of pointers can be quite deliberate. Splitting objects across multiple allocations would necessitate inserting/dereferencing pointers regardless of what was written in the source code. This makes object size, memory access patterns, and potentially performance quite unpredictable.
There are several aspects to the efficiency component:
- The compiler cannot use fixed offsets to access fields of an object if the object can be split across multiple allocations at runtime.
- There is additional bookkeeping required on the runtime (OS/kernel) to ensure that a split objects gets allocated/deallocated correctly.
- Splitting an object across multiple allocations would require pointers to be inserted/dereferenced at some point or another. While you are correct in stating that RAM allows for approximately the same speed in accessing arbitrary memory locations, the same cannot be said for the CPU cache. Memory is quite slow compared to the CPU cache, and the cache is usually very limited in space compared to RAM. Thus, for optimal performance, you typically want predictable access patterns that are located in "close" memory areas. Pointers usually make doing so difficult, if not impossible.
- Object size is no longer predictable, which is very problematic for more memory-constrained devices (or if you want to pack as much data as possible into cache).
- Probably more I'm not thinking of at the moment
> "But such piece-wise allocation is required if we want a record syntax were we can just specify a value for a base class." I don't understand this claim at all. Why is this required? What does it mean to "specify a value for a base class" - is this shorthand for "specify a value for a field of a base class"?
I'm guessing that they mean that they want the ability to specify the values for the base class (or the fields of the base class) without having to allocate memory for the unused field(s) of the subclass(es) while still retaining the ability to specify subclass fields later.
- scubbo 7y agoFascinating - thanks for your input! I wasn't aware of the CPU cache's extra limitation - that makes a lot of sense. And, yes - as you say, it makes perfect sense that having all the data of an object colocated (and at predictable offsets from one another) would make for a more efficient operating experience.