我正在考虑Java中的内存分配,即其中 存储内存位置方法,字段和对象。
假设我有2个班级
import java.util.*;
class ABC
{
int field;
List<Integer>l;
}
class XYZ
{
int x,y,z;
static int p;
void fun(ABC a){
a.field = 10;
a.l = new ArrayList<Integer>(10);
a.l.add(10);
}
}
public class Simulator{
public static void main(String[] arg){
XYZ tmp_1 = new XYZ();
ABC tmp_2 = new ABC();
tmp_1.fun(tmp_2);
System.out.println(tmp_2.l);
}
}
现在将为每个数据成员分配内存,分配函数和对象?
我的想法是对象,数据成员将存储在堆中,但我不确定函数及其数据成员?
答案 0 :(得分:4)
是的,所有对象都在堆上分配。即:使用new
创建的所有内容都将放在堆上。因此,这些对象的所有字段也都在堆上。
我想你是指函数中的局部变量和参数。它们被放置在堆栈上(对于函数的每次调用)。但请注意,当函数变量/参数是引用类型时,它们指向的实际对象在堆上,但变量/参数本身将在堆栈上(类似于C / C ++中的指针)。另一方面,基本类型的函数变量/参数(如int
,double
等)将完全在堆栈上。与主题略有相关但又相关的是boxing的概念。
函数本身是静态代码,存储在所有可执行代码所在的内存的特殊部分中。请注意,类的所有实例共享相同的功能(即,即使这些函数是实例函数),也不会使用新创建的对象创建“新函数”。因此,当您在对象上调用实例函数时,会向该函数传递一个特殊的this
引用(它是函数的隐式参数)。这就是函数知道它应该在哪些对象上运行的方式。
答案 1 :(得分:1)
以下是您存储或提及的不同内容的细分:
局部变量和方法/构造函数参数可以包含原始值或对象或数组的引用。 (它们不能包含对象或数组本身。)本地和参数存储在激活帧中(使用JLS术语),这些帧存储在线程的堆栈中。线程堆栈是典型JVM中的非堆内存。
对象和数组在堆内存中表示。
实例字段(包含基元或参考值)存储在对象中,因此存储在堆中。
数组元素(基本值或引用值)和数组的长度存储在数组中,因此存储在堆中。
静态字段存储在称为静态帧的特殊帧中。这些帧存储在堆中。
Java方法的代码(字节代码和本机代码形式)通常由存储在堆中的代码块表示。
请注意,上述内容基于典型 JVM中发生的情况。事实上,Java语言规范并没有要求将事物存储在堆栈或堆中。堆栈内存和堆内存这两个术语根本不会出现在JLS中,可以想象可以使用其他内存组织方案。
此外,“堆”过度简化,因为HotSpot JVM / GC通常将堆分成具有不同特征的区域。例如,堆的“permgen”区域(分配静态帧和代码块)只是很少收集垃圾。
答案 2 :(得分:0)
补充以前的答案: