方法住在哪里?堆栈还是堆?

4 java heap stack jvm

我知道局部变量和方法的参数都存在于堆栈中,但我无法弄清楚Java的实际方法在哪里?

如果我声明任何Thread对象,如:

Thread t=new Thread();
t.start();
Run Code Online (Sandbox Code Playgroud)

所以这意味着除了main方法之外,我已经创建了一个单独的方法调用.这是什么意思?这是否意味着在堆栈内存上调用单独的方法序列?我对吗?

Bri*_*new 8

每个线程都分配有自己的堆栈.

本文很好地介绍了Java进程中的内存分离.

在Java虚拟机内部,每个线程都被授予一个Java堆栈,其中包含其他线程无法访问的数据,包括线程调用的每个方法的局部变量,参数和返回值.堆栈上的数据仅限于基本类型和对象引用.在JVM中,无法将实际对象的图像放在堆栈上.所有对象都驻留在堆上.

我已经看到很多场景,客户端已经实现了大量线程化的服务器,因为每个线程都做得很少,并且它们会遇到内存问题.那是因为每个线程都分配了自己的堆栈,这显然加起来了.我认为默认值是每个线程512k,但我没有找到一个规范的来源.


ape*_*ins 8

如果我没记错的话,方法代码本身将存在于内存的代码部分,而内部声明的变量将存在于堆栈中,并且对象将在堆上创建.在Java中,变量指针和原语存在于堆栈中,而任何创建的对象都存在于堆中.

对于(差)ASCII表示:

-------
|STACK|
-------
|FREE |
-------
|HEAP |
-------
|CODE |
-------
Run Code Online (Sandbox Code Playgroud)

在STACK表示堆栈的地方,FREE表示空闲内存,HEAP表示堆,CODE表示代码空间.

这就是我的记忆所说的 - 一些细节可能是错误的.


Pet*_*ter 6

堆栈由方法调用组成.java推入堆栈的是一个方法调用记录,它封装了该方法的所有变量(包括参数和本地实例化变量).当您启动Java应用程序时,main方法(自动包含args参数)是堆栈中唯一的东西:

main(args)
Run Code Online (Sandbox Code Playgroud)

当你创建一个Foo对象并调用foo.method()时,堆栈现在看起来像:

method()
main(args)
Run Code Online (Sandbox Code Playgroud)

当方法被调用时,它们被推入堆栈,当它们返回时,它们被从堆栈中移除或"弹出".在声明和使用变量时,堆栈条目(对应于当前方法(在堆栈的顶部))增长以包括变量的大小.

对于带有线程的示例,每个线程都有自己的堆栈,该堆栈独立于彼此的线程堆栈而存在.