我知道本地变量和方法参数存在堆栈中,但是我无法确定Java中的方法实际上存在于哪里?
如果我声明任何线程对象,比如:
Thread t=new Thread();
t.start();
所以这意味着我已经创建了一个与主方法分开的方法调用。这是什么意思?它是否意味着在堆栈内存上调用单独的方法序列?我的理解正确吗?
我知道本地变量和方法参数存在堆栈中,但是我无法确定Java中的方法实际上存在于哪里?
如果我声明任何线程对象,比如:
Thread t=new Thread();
t.start();
所以这意味着我已经创建了一个与主方法分开的方法调用。这是什么意思?它是否意味着在堆栈内存上调用单独的方法序列?我的理解正确吗?
如果我没记错的话,方法代码本身将存储于内存的代码区域,而内部声明的变量将存储于堆栈中,对象将被创建于堆中。在Java中,变量指针和基本类型将存储于堆栈中,而任何创建的对象将存储于堆中。
一个(不好的)ASCII表示:
-------
|STACK|
-------
|FREE |
-------
|HEAP |
-------
|CODE |
-------
其中,STACK代表栈,FREE代表空闲内存,HEAP代表堆,CODE代表代码空间。
这是我的记忆 - 一些细节可能不正确。
栈由方法调用组成。Java 将方法调用记录推入栈中,该记录封装了该方法的所有变量(包括参数和本地实例化变量)。当您启动 Java 应用程序时,主方法(自动包括 args 参数)是栈上唯一的东西:
main(args)
method()
main(args)
栈包含所有本地变量和所有活动的方法调用。堆则保存其他所有内容。
至于您的子问题:它意味着将创建一个具有自己专用内存的新栈。而您的新线程将共享jvm分配的总堆空间(内存)。
堆被分成多个代。
字节码及其对应的JIT编译后的机器码存储在所谓的永久代中,与字符串和其他类数据一起。
尽管它被称为“永久”代,但它仍然可以进行垃圾回收。一些库、框架和JVM语言会在运行时生成字节码,因此永久代有时需要清理。就像堆的其他代一样,但(通常希望)不太频繁。