Java 默认堆栈大小是多少,它可以增长,它如何与垃圾收集一起工作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20030120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the default stack size, can it grow, how does it work with garbage collection?
提问by Batty
I understand that each thread has its own stack
. Primitive types and references are kept on the stack, and that no object is kept on the stack.
我知道每个线程都有自己的stack
. 原始类型和引用保存在堆栈中,并且没有对象保存在堆栈中。
My questions are:
我的问题是:
- How much can a stack grow? (like with the paramters -
Xms
and -Xmx
) - Can we limit its growth?
- Does the stack have a default minimum value and maximum value?
- How does garbage collection work on the stack?
- 一个堆栈可以增长多少?(就像参数 -
Xms
和 -Xmx
) - 我们可以限制它的增长吗?
- 堆栈是否有默认的最小值和最大值?
- 垃圾收集如何在堆栈上工作?
采纳答案by StarPinkER
How much a stack can grow?
一个堆栈可以增长多少?
You can use a VM option named ss
to adjust the maximum stack size. A VM option is usually passed using -X{option}. So you can use java -Xss1M
to set the maximum of stack size to 1M.
您可以使用名为的 VM 选项ss
来调整最大堆栈大小。VM 选项通常使用 -X{option} 传递。因此您可以使用java -Xss1M
将堆栈大小的最大值设置为 1M。
Each thread has at least one stack. Some Java Virtual Machines(JVM) put Java stack(Java method calls) and native stack(Native method calls in VM) into one stack, and perform stack unwinding using a Managed to Native Frame, known as M2NFrame. Some JVMs keep two stacks separately. The Xss
set the size of the Java Stack in most cases.
每个线程至少有一个堆栈。一些 Java 虚拟机 (JVM) 将 Java 堆栈(Java 方法调用)和本机堆栈(VM 中的本机方法调用)放在一个堆栈中,并使用被称为 M2NFrame 的 Managed to Native Frame 执行堆栈展开。一些 JVM 分别保留两个堆栈。在Xss
大多数情况下设置Java堆栈的大小。
For many JVMs, they put different default values for stack size on different platforms.
对于许多 JVM,它们在不同平台上为堆栈大小设置了不同的默认值。
Can we limit this growth?
我们可以限制这种增长吗?
When a method call occurs, a new stack frame will be created on the stack of that thread. The stack will contain local variables, parameters, return address, etc. In java, you can never put an object on stack, only object reference can be stored on stack. Since array is also an object in java, arrays are also not stored on stack. So, if you reduce the amount of your local primitive variables, parameters by grouping them into objects, you can reduce the space on stack. Actually, the fact that we cannot explicitly put objects on java stack affects the performance some time(cache miss).
当发生方法调用时,将在该线程的堆栈上创建一个新的堆栈帧。堆栈将包含局部变量、参数、返回地址等。在java中,您永远不能将对象放入堆栈,只能将对象引用存储在堆栈中。由于数组在java中也是一个对象,所以数组也不存储在栈上。因此,如果通过将它们分组到对象中来减少本地原始变量和参数的数量,则可以减少堆栈空间。实际上,我们不能显式地将对象放在 Java 堆栈上这一事实会在一段时间内影响性能(缓存未命中)。
Does stack has some default minimum value or default maximum value?
堆栈是否有一些默认最小值或默认最大值?
As I said before, different VMs are different, and may change over versions. See here.
正如我之前所说,不同的虚拟机是不同的,并且可能会随着版本的变化而变化。见这里。
how does garbage collection work on stack?
垃圾收集如何在堆栈上工作?
Garbage collections in Java is a hot topic. Garbage collection aims to collect unreachable objects in the heap. So that needs a definition of 'reachable.' Everything on the stack constitutes part of the root set references in GC. Everything that is reachable from every stack of every thread should be considered as live. There are some other root set references, like Thread objects and some class objects.
Java 中的垃圾收集是一个热门话题。垃圾收集旨在收集堆中无法访问的对象。所以这需要一个“可达”的定义。堆栈上的所有内容都构成了 GC 中根集引用的一部分。从每个线程的每个堆栈可访问的所有内容都应视为活动的。还有一些其他的根集引用,比如 Thread 对象和一些类对象。
This is only a very vague use of stack on GC. Currently most JVMs are using a generational GC. This articlegives brief introduction about Java GC. And recently I read a very good articletalking about the GC on .net. The GC on oracle jvm is quite similar so I think that might also help you.
这只是 GC 上堆栈的一个非常模糊的用法。目前大多数 JVM 都使用分代 GC。本文简要介绍了 Java GC。最近我读了一篇关于 .net 上 GC的非常好的文章。oracle jvm 上的 GC 非常相似,所以我认为这也可能对您有所帮助。
回答by Vincent van der Weele
As you say, local variables and references are stored on the stack. When a method returns, the stack pointer is simply moved back to where it was before the method started, that is, all local data is "removed from the stack". Therefore, there is no garbage collection needed on the stack, that only happens in the heap.
正如您所说,局部变量和引用存储在堆栈中。当一个方法返回时,堆栈指针只是简单地移回到方法启动之前的位置,即所有本地数据都“从堆栈中移除”。因此,堆栈上不需要垃圾回收,只发生在堆中。
To answer your specific questions:
要回答您的具体问题:
- See this questionon how to increase the stack size.
- You can limit the stack growth by:
- grouping many local variables in an object: that object will be stored in the heap and only the reference is stored on the stack
- limit the number of nested function calls (typically by not using recursion)
- For windows, the default stack size is 320k for 32bit and 1024k for 64bit, see this link.