[英]Memory Allocation in JVM
我在考虑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);
}
}
现在将为每个数据成员,功能和对象分配内存的位置是什么?
我的想法是对象,数据成员将存储在Heap中,但是我不确定函数及其数据成员吗?
是的,所有对象都分配在堆上。 即:用new
创建的所有内容都将放在堆中。 因此,此类对象的所有字段也都在堆上。
我想您指的是函数中的局部变量和参数。 这些被放置在堆栈上(对于函数的每次调用)。 但是请注意,当函数变量/参数是引用类型时,它们所指向的实际对象在堆上,但是变量/参数本身将在堆栈上(类似于C / C ++中的指针)。 另一方面,基本类型(如int
, double
等)的函数变量/参数将完全位于堆栈中。 与该主题略相关但相关的是拳击的概念。
函数本身是静态代码,并存储在所有可执行代码所在的内存的特殊部分中。 请注意,一个类的所有实例共享相同的功能(即,即使这些功能是实例功能 ,也不会使用新创建的对象来创建“新功能”)。 因此,当您在对象上调用实例函数时,特殊的this
引用将传递给该函数(它是该函数的隐式参数)。 这就是函数知道应该对哪些对象执行操作的方式。
以下是您所引用或暗示的不同事物如何存储的细分:
局部变量和方法/构造函数参数可以包含原始值或对对象或数组的引用。 (它们本身不能包含对象或数组。)局部变量和参数存储在激活框架中 (以使用JLS术语),并且这些框架存储在线程的堆栈中。 线程堆栈是典型JVM中的非堆内存。
对象和数组在堆内存中表示。
实例字段(包含原始值或引用值)存储在对象中,因此也存储在堆中。
数组元素(原始值或参考值)以及数组的长度存储在数组中,因此也存储在堆中。
静态字段存储在称为静态帧的特殊帧中。 这些帧存储在堆中。
Java方法的代码(以字节代码和本机代码形式)通常由存储在堆中的代码块表示。
请注意,以上内容基于典型 JVM中发生的情况。 实际上,Java语言规范并未强制要求将事物存储在堆栈或堆中。 术语堆栈内存和堆内存根本没有出现在JLS中,可以想象可以使用其他内存组织方案。
另外,“堆”过于简化了,因为HotSpot JVM / GC通常将堆分为具有不同特征的区域。 例如,堆的“ permgen”区域(分配了静态帧和代码块的区域)很少被垃圾收集。
为了补充先前的答案:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.