4 ms·
The weak generational hypothesis states that most objects are short-lived. Doesn't this mostly apply to the classical OO style of coding that developed in Smal
by stcredzero 10y ago
The weak generational hypothesis states that most objects are short-lived.
Doesn't this mostly apply to the classical OO style of coding that developed in Smalltalk and early Java? More recently, there have been styles of coding which emphasize pass by value in order to have better cache locality in generated code. The old style of "composition/organization by indirection" resulted lots of followed pointers, resulting in more cache misses, resulting in slower execution.
There is no strategy that fits all when it comes to memory management. :)
There is a nice overall strategy being followed by the Go community here. The emphasis in golang seems to be on pass by value when feasible, and keeping an eye out for reducing GC pressure. This is synergistic with GC optimized for concurrency and short pause times and also synergistic with good profiling tools for identifying the source of allocations.
This strategy makes it fairly easy to first make applications that work, then optimize them. The amount of mental effort is far less than that required to manage memory. The consequences for making a mistake are far less harsh, and correcting mistakes is fairly easy.
- willsewell 10y agoFrom my understanding, the weak generational hypothesis holds for the majority of programs in general. In fact, it is particularly true of language that encourage immutable data ( because new data is created rather than existing data updated). I don't see why it would apply particularly to OO languages, in fact, I would assume that passing pointers around would result in less short-lived objects due to less copying.
- stcredzero 10y agoFrom my understanding, the weak generational hypothesis holds for the majority of programs in general. But in Smalltalk like languages, the GC has to deal with "all of it," including objects that were allocated "on the stack." Because in most cases, outside of optimized cases like SmallInteger, my understanding is that objects allocated on the heap no matter what, and only that pointer reference was allocated on the stack. It applied very well to Smalltalk. But there was a tendency to have objects for everything, and even a stack allocation meant a heap allocation. I don't see why it would apply particularly to OO languages, in fact, I would assume that passing pointers around would result in less short-lived objects due to less copying. Composition facilitated by object reference can result in styles where the granularity is small, so there are lots of objects. When a new user defined Object mans a new allocation on the heap, this means a lot throughput for the GC.
- bjourne 10y agoWell, it is an hypothesis and not a theorem so it hasn't been proven. But the tendency of most objects to be short-lived is universal and doesn't vary depending on programming language. I believe you are thinking of objects which are allocated on the stack as not being objects. But they are just as much objects all objects allocated on the heap. The difference is that stack-allocated objects have a very limited lifetime as they go out of scope when the procedure in which they are allocated returns. That makes allocating them extremely cheap. In fact, modern compilers perform optimizations called escape analysis to determine if the object allocated is only being used in the procedure. If so, it doesn't "escape" it and it can be allocated on the stack instead. Go's value types means they are putting the burden on choosing whether to allocate on the stack or on the heap on the programmer. Often the programmer does a much better job at deciding those things than the compiler, which is good for performance. But it adds one extra thing that the programmer has to think about. It's a classic engineering trade-off between language complexity and performance. I prefer languages that sacrifices performance for simplicity, but there is nothing wrong with Go's choice either.
- stcredzero 10y agoI believe you are thinking of objects which are allocated on the stack as not being objects. Of course they are still objects. However, those are objects that don't have to be collected, though they are still involved as "roots" or starting places for GC scan. The difference is that stack-allocated objects have a very limited lifetime as they go out of scope when the procedure in which they are allocated returns. That makes allocating them extremely cheap. Which is the whole point of styles that emphasize pass by value and allocating on the stack. Thanks for repeating the basics for 3rd parties that might find it useful. Go's value types means they are putting the burden on choosing whether to allocate on the stack or on the heap on the programmer. Often the programmer does a much better job at deciding those things than the compiler, which is good for performance. But it adds one extra thing that the programmer has to think about. Good paraphrase of what I said. Thinking about those things as one codes is kind of optional, in that the program will still be correct and will still run. It's probably best left to a later optimization stage, though there will still be some burden on the programmer to avoid pathological performance. In any case, it's less burden than outright memory management.