Data access performance in heap and stack and object allocation

Asked

Viewed 484 times

17

Data access in the stack is faster than in heap? And why allocate an object to heap?

  • The concepts of stack and heap are not part of the C definition. It is not mandatory that all C implementations use this memory space splitting scheme.

  • Take a look at [tour]. You can accept an answer if it solved your problem. You can vote on every post on the site as well. Did any help you more? You need something to be improved?

1 answer

15

Yes, the stack not only is it faster than the heap but it’s also easier to manipulate it. The allocation in heap is basically due to these reasons:

  1. An object is too big to fit in stack.

The area reserved for the stack is usually fixed (it is possible to increase its size but this is not available in all situations and is a complicated process and has disadvantages) and is usually very small (around 1MB in most cases of Windows desktop applications, may be smaller in devices with little memory, but has cases that may have up to 4GB or more in some cases). Obviously we can’t abuse what we put in it. Not only because big things may not fit, but even many size allocations not so big but beyond the trivial can end up popping the size as well.

If it were bigger, it would waste memory most of the time and not solve all the problems. In most cases one should not allocate more than a few bytes in stack. Some use a rule of maximum size 2 words, or a fixed quantity of bytes. This can go around 64 bytes (typical size of cache line processor), but it is only an initial consideration to trigger an alert, should not be a fixed rule.

  1. Object size is undetermined or variable.

If you do not know the size of the object beforehand, you cannot count that the object is small enough. Even if you know the maximum size and know that it is small, without knowing the exact size it is difficult to reserve space in memory. A stack is a continuous memory that needs to be reserved. Although it is possible to allocate any size defined at runtime this has implications that make it difficult to use. Using an object without knowing the size is not a big problem, it makes the mechanism much more complex and less performatic. You create a indirect.

  1. An object must survive the end of its scope.

This is one of the important points, probably the most important. When I talk about scope, in general is not any scope, but mainly the scope of the function or block. That is, if an object needs to be accessed when the function ends there are only two possibilities:

a) allocates it to stack and copies it to the calling function when the current function ends;

b) allocate at another location that does not need to be released at the end of the function.

Small objects being copied at the end of the function is not a problem, in fact there will always be a copy when it passes some return to the calling function, but when the object is large the copy will be only from reference for object in the heap. This copy is required because the data of the current function is unmounted at the end of the scope execution.

As its name says, stack is a stack of data that will be stacked when it enters a new scope and automatically pops at the end of it, this is what gives the ease and speed of this mechanism. When it pops nothing guarantees that the data remains there, it can be overwritten soon after by some other code executed in the calling function that has just regained control of execution. To ensure that it will be there it must be copied. Large data copies cost expensive, and don’t even need to be that large.

To avoid expensive copying, allocate the object in another location that does not function as a stack, which does not have continuous memory, and access it in a way indirect. It does not matter if the data you want to preserve is referenced directly in a return or within another data structure such as closure or a collection that has already been passed by reference to the function. This location is the heap.

  1. A release may be required out of allocation order.

For some reason you may need to control the order in which the objects will be released. This is not possible in the stack that always makes a release LIFO (last in, first out) which is the base of the stack.

  1. It is possible to recover from an allocation error in heap.

In general when trying to allocate memory in heap and cannot, it is possible to verify and do something so that the application does not break and who knows how to proceed without bumps. If the allocation of the stack fail, most likely the application will break without further ceremony. Languages do not usually have effective mechanisms to treat this error, because it is difficult to solve the problem properly, when it is not impossible, and it is slow.

  1. Apis that the programmer has no control over the functioning require their use.

Of course it could be different and if there was the definition that nothing could use the heap this problem would not happen, but this is not only a real problem in the way things actually exist and nothing can be done about it, but it also makes sense to be so. The heap is not a continuous memory, it can be blended and provided by the operating system for the application to make flexible use in its various parts. So disparate Apis can work together without one affecting the other. Of course, when they need to communicate, they either do it through a specific area designated for this and with their own well-defined contracts, or they access a common area with very well-defined contracts, especially if they can access at the same time. This becomes impractical in stack.

They’ve already written a response in the OS with a code showing the difference in performance from one to the other. It’s really brutal. I won’t put the code to run online because it needs to be compiled with flags specific to produce a relevant result, but in the answer we can see 30 to 50 times the difference. Even so, allocate in the heap may be good enough for what you need.

Of course there are optimizations that make it better. There are Garbage Collectors that allow allocation in the heap almost at the same time of stack, but of course there are other deficiencies in it, there is no free lunch.

No one has been able to do what they need most efficiently in decades that we use computers. In computing everything is tradeoff.

Few people remember that there is an even faster allocation, which is static. Memory that is already allocated at the beginning of the execution is unbeatable. But it obviously doesn’t have much flexibility. The allocation in the stack is called automatic and not static as some think.

To learn more about the operation of these concepts already has a another question on the subject.

  • It is worth noting that Leak in the stack is a high complexity case to identify. It even has specific tools to assist in these cases.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.