简体   繁体   English

为什么使用堆栈而不是堆?

[英]why use the stack instead of heap?

I see only disadvantage of this: you can get StackOverflow :) Why not use only Heap? 我只看到了这个缺点:你可以得到StackOverflow :)为什么不只使用堆?

In Java, C, C++ the parameters to functions are passed on stack. 在Java,C,C ++中,函数的参数在堆栈上传递。 The plain variables inside functions bodies are created in stack. 函数体内的普通变量是在堆栈中创建的。

As I know the stack is limited per thread, has some default values, but relative low: 1-8 Mb. 据我所知,每个线程的堆栈是有限的,有一些默认值,但相对较低:1-8 Mb。 Why not use the Heap instead of Stack. 为什么不使用堆而不是堆栈。 Both are in memory, just the OS make a separation from Address A to B is Heap and from C to D is Stack. 两者都在内存中,只是操作系统从地址A到B分离是堆,而从C到D是堆栈。

There are variable arguments. 有可变的参数。 It says there are 10 variable of 4 byte each. 它说有10个变量,每个变量4个字节。 If you read 11 than you maybe read some data a "memory" trash, and maybe exactly that you want for hacking or maybe you get a Segmentation fault ... if the OS detects you as bad boy. 如果您阅读11,那么您可能会读取一些“内存”垃圾,也许正是您想要的黑客攻击,或者您可能会遇到分段错误...如果操作系统检测到您是个坏孩子。 :) - So security can't be a reason for use Stack. :) - 所以安全性不能成为使用Stack的理由。

Performance is one of many reasons: memory in the stack is trivial to book-keep; 性能是众多原因之一:堆栈中的内存对于预订来说是微不足道的; it has no holes; 它没有洞; it can be mapped directly into the cache; 它可以直接映射到缓存中; it is attached on a per-thread basis. 它是基于每个线程附加的。

In contrast, memory in the heap is, well, a heap of stuff; 相比之下,堆中的内存就是一堆东西; it is more difficult to book-keep; 预订比较困难; it can have holes. 它可以有洞。

Check out this answer (excellent, in my opinion) explaining some other differences. 看看这个答案 (在我看来很好)解释其他一些差异。

Others have already mentioned that the stack can be faster due to simplicity of incrementing/decrementing the stack pointer. 其他人已经提到由于递增/递减堆栈指针的简单性,堆栈可以更快。 This is, however, quite a ways from the whole story. 然而,这与整个故事完全不同。

First of all, if you're using a garbage collector that compacts the heap (ie, most modern collectors) allocation on the heap isn't much different from allocation on the stack. 首先,如果您使用的是压缩堆的垃圾收集器(即大多数现代收集器),堆上的分配与堆栈上的分配没有太大区别。 You simply keep a pointer to boundary between allocated and free memory, and to allocate some space, you just move that pointer, just like you would on the stack. 您只需保持指向已分配和可用内存之间边界的指针,并分配一些空间,您只需移动该指针,就像在堆栈上一样。 Objects that will have extremely short lives (like the locals in most functions) cost next to nothing in a GC cycle too. 寿命极短的物体(如大多数功能中的当地人)在GC循环中几乎没有任何成本。 Keeping a live object accessible takes (a little) work, but an object that's no longer accessible normally involves next to no work. 保持活动对象可访问需要(一点点)工作,但是不再可访问的对象通常涉及无法工作。

There is, however, often still a substantial advantage to using the stack for most variables. 然而,对于大多数变量使用堆栈通常仍然具有实质性的优点。 Many typical programs tend to run for fairly extended periods of time using nearly constant amounts of stack space. 许多典型的程序倾向于使用几乎恒定的堆栈空间运行相当长的时间段。 They enter one function, create some variables, use them for a while, pop them off the stack, then repeat the same cycle in another function. 它们输入一个函数,创建一些变量,使用它们一段时间,将它们从堆栈中弹出,然后在另一个函数中重复相同的循环。

This means most of the memory toward the top of the stack is almost always in the cache. 这意味着朝向堆栈顶部的大部分内存几乎总是在缓存中。 Most function calls are re-using memory that was just vacated by the previous function call. 大多数函数调用都是重用前一个函数调用腾出的内存。 By reusing the same memory continuously, you end up with considerably better cache usage. 通过不断重复使用相同的内存,您最终可以获得更好的缓存使用率。

By contrast, when you allocate items in the heap, you typically end up allocating separate space for nearly every item. 相比之下,当您在堆中分配项目时,通常最终会为几乎每个项目分配单独的空间。 You cache is in a constant state of "churn", throwing away the memory for objects you're no longer user to make space for newly allocated ones. 缓存处于“churn”的常量状态,为不再是用户的对象丢弃内存,为新分配的对象腾​​出空间。 Unless you use a minuscule heap, the chances of re-using an address while it's still in the cache are nearly nonexistent. 除非你使用一个微小的堆,否则当它仍在缓存中时重新使用地址的可能性几乎不存在。

I'm sure this is answered a million times online, but... 我确信这在网上得到了一百万次回答,但......

Because you don't want every method call to be a memory allocation (slow). 因为您不希望每个方法调用都是内存分配(慢)。 So, you pre-allocate your stack. 所以,你预先分配你的堆栈。

Some more reasons listed here (including security). 此处列出的更多原因(包括安全性)。

The answer is that you get holes when you allocate and de-allocate on the heap. 答案是,在堆上分配和取消分配时会出现漏洞。 This means that it gets more and more difficult to allocate memory since the places that are available are different sizes. 这意味着分配内存变得越来越困难,因为可用的地方大小不同。 The stack only reserves what is needed and gives it all back when you get out of scope. 堆栈仅保留所需的内容,并在您超出范围时将其全部返回。 No hassle. 没有麻烦。

If everything was on the stack, each time you passed those values on, they would have to be copied. 如果所有内容都在堆栈中,那么每次传递这些值时,都必须复制它们。 However, unlike the heap, it doesn't need to be cleverly managed - items on the heap require garbage collection. 但是,与堆不同,它不需要巧妙地管理 - 堆上的项目需要垃圾回收。

So they work in two different ways that suit two different uses. 因此,它们以两种不同的方式工作,适合两种不同的用途。 The stack is a quick and lightweight home for values to be held for a short time whereas the heap allows you to pass objects around without copying them. 堆栈是一个快速轻量级的主页,可以在短时间内保存值,而堆允许您在不复制它们的情况下传递对象。

Neither stack nor heap is perfect for every scenario - that is why they both exist. 堆栈和堆都不适用于每种情况 - 这就是它们都存在的原因。

Using the heap requires "requesting" a bit of memory from the heap, using new or some similar function. 使用堆需要使用new或类似的函数从堆中“请求”一些内存。 Then, when it's finished, you delete the it again. 然后,当它完成后,再次delete它。 This is very useful for variables that are long-lived and/or that take up quite a bit of space (or take up an "unknown at compile-time" space - for example if you read a string into a variable from a file, you don't necessarily know how much space it needs, and it's REALLY annoying to get a message from the program saying "String too large on line X in file Y"). 这对于长寿命和/或占用相当大的空间(或占用“编译时未知”空间)的变量非常有用 - 例如,如果从文件中读取变量的字符串,你不一定知道它需要多少空间,从程序中得到一条消息“文件Y中第X行的字符串太大”真的很烦人。

On the other hand, the stack is "free" both when it comes to allocating and de-allocating (technically, any function that uses stack-space will need one extra instruction for the allocation of the stackspace, but compared to the several hundred or thousands that a call to new will involve, it's not noticeable). 另一方面,堆栈在分配和解除分配时都是“空闲的”(从技术上讲,任何使用堆栈空间的函数都需要一个额外的指令来分配堆栈空间,但与数百或成千上万的呼吁涉及new ,这是不明显的)。 Of course, class objects will still have to have their respective constructors called, which may take almost any amount of time to complete, but that is true regardless of how/where the storage is allocated from. 当然, class对象仍然必须调用它们各自的构造函数,这可能需要几乎任何时间才能完成,但无论分配存储的方式/位置如何都是如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在Java中将follow数组放置在堆而不是堆栈 - Why is the follow array placed on heap instead of stack in Java 为什么在实现优先级队列时使用堆而不是二叉树? - Why use heap instead of binary tree when implementing priority queue? java中可以将对象存储在堆栈上而不是堆上吗? - Can an object be stored on the stack instead of the heap in java? 为什么在 Java 中对象是在堆上而不是在堆栈上创建的? - Why are objects made on the heap and not on the stack in Java? 数组如何在Java中使用堆栈空间和堆空间? - How arrays use stack and heap space in Java? 当我在程序中创建堆栈时,为什么它存储在堆中而不是堆栈中? - When i create a stack in the program, why it is storing in heap not stack? Tomcat使用队列的堆栈堆栈为什么为什么最好使用堆栈而不是队列或任何其他池呢? - Tomcat uses stack intsead of queue?Why it is better use stack instead of queue or anyother pool? 为什么在Java中使用堆内存 - why use Heap Memory in Java 两种语言是否在 ram 上使用相同的堆栈和堆? - Does two languages use the same stack and heap on the ram? 在方法中使用实例变量时的堆和堆栈(Java 内存) - Heap and Stack when I use an instance variable in a method (Java Memory)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM