java 方法在哪里?堆栈还是堆?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1208695/
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
Where methods live? Stack or in Heap?
提问by Peter
I know that local variables and paramters of methods live in stack, but I not able to figure out where does actually methods live in case of Java?
我知道方法的局部变量和参数存在于堆栈中,但我无法弄清楚在 Java 的情况下实际方法存在于何处?
If I declare any Thread object like:
如果我声明任何 Thread 对象,例如:
Thread t=new Thread();
t.start();
So it means I've created a separate calling of methods apart from main method. What does it mean? Does it mean calling of separate sequence of methods over Stack memory? Am I right?
所以这意味着除了 main 方法之外,我已经创建了一个单独的方法调用。这是什么意思?这是否意味着在堆栈内存上调用单独的方法序列?我对吗?
回答by Brian Agnew
Each thread is allocated its own stack.
每个线程都分配有自己的堆栈。
This articlehas a good introduction to the memory separation within a Java process.
这篇文章很好地介绍了 Java 进程中的内存分离。
Inside the Java virtual machine, each thread is awarded a Java stack, which contains data no other thread can access, including the local variables, parameters, and return values of each method the thread has invoked. The data on the stack is limited to primitive types and object references. In the JVM, it is not possible to place the image of an actual object on the stack. All objects reside on the heap.
在 Java 虚拟机内部,每个线程都被授予一个 Java 堆栈,其中包含其他线程无法访问的数据,包括线程调用的每个方法的局部变量、参数和返回值。堆栈上的数据仅限于原始类型和对象引用。在 JVM 中,不可能将实际对象的图像放在堆栈上。所有对象都驻留在堆上。
I've seen many scenarios where clients have implemented hugely threaded servers on the basis that each thread does very little, and they run into problems with memory. That's because each thread is allocated its own stack, and this (obviously) adds up. I thinkthe default value is 512k per thread, but I've not found a canonical source for that.
我见过很多场景,客户端在每个线程做的很少的基础上实现了巨大的线程服务器,并且它们遇到了内存问题。那是因为每个线程都分配了自己的堆栈,这(显然)加起来了。我认为每个线程的默认值是 512k,但我还没有找到一个规范的来源。
回答by aperkins
If I remember correctly, the method code itself will live in the code portion of memory, while the variables declared internally will live in the stack, and the objects will be created on the heap. In Java, the variable pointers and primitives live on the stack, while any created objects live in the heap.
如果我没记错的话,方法代码本身将存在于内存的代码部分,而内部声明的变量将存在于堆栈中,而对象将在堆上创建。在 Java 中,变量指针和原语存在于堆栈中,而任何创建的对象都存在于堆中。
For a (poor) ASCII representation:
对于(较差的)ASCII 表示:
-------
|STACK|
-------
|FREE |
-------
|HEAP |
-------
|CODE |
-------
Where the STACK represents the stack, FREE represents free memory, HEAP represents the heap, and CODE represents the code space.
其中STACK代表栈,FREE代表空闲内存,HEAP代表堆,CODE代表代码空间。
This is what my memory says - some of the details might be wrong.
这就是我的记忆所说的 - 一些细节可能是错误的。
回答by Peter
The stack is comprised of method invocations. What java pushes onto the stack is a method invocation record, which encapsulates all the variables (both parameters and locally instantiated variables) for that method. When you start a Java application, the main method (which automatically includes the args parameter) is the only thing on the stack:
堆栈由方法调用组成。java压入栈的是一个方法调用记录,它封装了该方法的所有变量(包括参数和本地实例化的变量)。当您启动 Java 应用程序时,main 方法(自动包含 args 参数)是堆栈中唯一的内容:
main(args)
When say you create a Foo object and call foo.method(), the stack now looks like:
当你创建一个 Foo 对象并调用 foo.method() 时,堆栈现在看起来像:
method()
main(args)
As methods get called, they are pushed onto the stack, and as they return, they are removed or "popped" from the stack. As variables are declared and used the stack entry, which corresponds to the current method (at the top of the stack), grows to include the size of the variable.
当方法被调用时,它们被压入堆栈,当它们返回时,它们被从堆栈中移除或“弹出”。随着变量的声明和使用,对应于当前方法(位于堆栈顶部)的堆栈条目会增长以包含变量的大小。
For your example with threads, each thread will have its own stack which exists independent of each other thread's stack.
对于您的线程示例,每个线程都有自己的堆栈,该堆栈独立于其他线程的堆栈。
回答by Chris Vest
The heap is split up into multiple generations.
堆被分成多代。
The bytecode, and its corrosponding JIT compiled machine code lives in the so called permanent generation, along with interned Strings and other class data.
字节码及其对应的 JIT 编译机器代码与内部字符串和其他类数据一起存在于所谓的永久代中。
Even though it is called the "permanent" generation, it can still be garbage collected. Some libraries, frameworks and JVM languages generate bytecode at run-time, so the permanent generation sometimes need clean up. Just like the other generations of the heap, but (one usually hopes) less frequently.
即使它被称为“永久”代,它仍然可以被垃圾收集。一些库、框架和 JVM 语言在运行时生成字节码,因此永久代有时需要清理。就像堆的其他代一样,但(通常希望)不那么频繁。
回答by KingInk
The stack contains all the local variables and all active method invocations. The heap hold everything else.
堆栈包含所有局部变量和所有活动方法调用。堆保存其他所有东西。
As for your sub question: it means a new stack is created with its own dedicated memory. While your new thread will share the total heap space (memory) allocated by the jvm
至于您的子问题:这意味着使用自己的专用内存创建了一个新堆栈。虽然您的新线程将共享 jvm 分配的总堆空间(内存)
回答by Harper Shelby
The actual bytecode and/or JIT'd code would live in the process's memory. There would likely only be one copy of it in the process memory, as all threads in a given process share that memory. Any variables sharedby those threads will be accessed by the methods in common. Variables local to the threads (even method local variables used within a thread) will be created within that thread's memory.
实际的字节码和/或 JIT 代码将存在于进程的内存中。进程内存中可能只有一个副本,因为给定进程中的所有线程共享该内存。这些线程共享的任何变量都将通过公共方法访问。线程的局部变量(甚至是线程中使用的方法局部变量)将在该线程的内存中创建。

