3 ms·
> An array in C++ has none of these things. However, consider that if the array is ever to be freed by free, then its size must be recorded anyway. That leaves
by scott_s 11y ago
> An array in C++ has none of these things. However, consider that if the array is ever to be freed by free, then its size must be recorded anyway. That leaves 8 bytes of overhead, which is likely comparable to the overhead caused by malloc's fragmentation.
Actually, no, it does not need to explicitly record the size of the allocation. Some implementations of malloc do this, using what are called "headers". But more modern allocators tend to use techniques which avoid this. They basically follow the pattern:
1. Maintain a list of slabs, where each slab contains objects of a particular size (say, 4, 8, 16, 32, etc, but not necessarily always doubling by 2).
2. You ensure that the slabs are in contiguous regions of virtual memory. The start is always on a page boundary.
3. For each page, you record its meta-information in either a giant array (for small address spaces), or a radix tree (for large address spaces).
4. Upon a free, you can just figure out what page an object lies in, then look up where its meta-information is. Then you have all of the information you need to free an object of a particular size. This function from an old project of mine shows all three techniques (headers, radix tree, giant array, also called a BIg Bag Of Pages): https://github.com/scotts/streamflow/blob/master/streamflow.c#L1386 https://github.com/scotts/streamflow/blob/master/streamflow....
Something else the author did not mention is that when it comes to performance tuning a GCed application, you have another variable: heap size. If the heap size is too small, you will GC too often. If the heap size is too large, your pauses when you do GC may be too large. It may require tuning to find that sweet spot.
Also, this came up in a previous thread (https://news.ycombinator.com/item?id=11058911 https://news.ycombinator.com/item?id=11058911), but the routines the author outlined for object allocation are quite similar to the ones used in modern implementations of malloc.
- Manishearth 11y ago(this only works if destructors/finalizers don't exist). You still need runtime type information if you want to be able to properly clean up a thing. E.g. what would happen if I put a `std::vector` on the GC heap?
- scott_s 11y agoIt works just fine with destructors and finalizers, as this is the underlying implementation of explicit memory allocation. One can build a true type-aware object system on top of it. This is how C++ does it. Please note that I am talking about techniques for explicit memory management, not garbage collection.
- Manishearth 11y agoOh, you were talking about a non-GC situation. Right.