繁体   English   中英

JVM中的内存分配

[英]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 ++中的指针)。 另一方面,基本类型(如intdouble等)的函数变量/参数将完全位于堆栈中。 与该主题略相关但相关的是拳击的概念。

函数本身是静态代码,并存储在所有可执行代码所在的内存的特殊部分中。 请注意,一个类的所有实例共享相同的功能(即,即使这些功能是实例功能 ,也不会使用新创建的对象来创建“新功能”)。 因此,当您在对象上调用实例函数时,特殊的this引用将传递给该函数(它是该函数的隐式参数)。 这就是函数知道应该对哪些对象执行操作的方式。

以下是您所引用或暗示的不同事物如何存储的细分:

  • 局部变量和方法/构造函数参数可以包含原始值或对对象或数组的引用。 (它们本身不能包含对象或数组。)局部变量和参数存储在激活框架中 (以使用JLS术语),并且这些框架存储在线程的堆栈中。 线程堆栈是典型JVM中的非堆内存。

  • 对象和数组在堆内存中表示。

  • 实例字段(包含原始值或引用值)存储在对象中,因此也存储在堆中。

  • 数组元素(原始值或参考值)以及数组的长度存储在数组中,因此也存储在堆中。

  • 静态字段存储在称为静态帧的特殊帧中。 这些帧存储在堆中。

  • Java方法的代码(以字节代码和本机代码形式)通常由存储在堆中的代码块表示。


请注意,以上内容基于典型 JVM中发生的情况。 实际上,Java语言规范并未强制要求将事物存储在堆栈或堆中。 术语堆栈内存和堆内存根本没有出现在JLS中,可以想象可以使用其他内存组织方案。

另外,“堆”过于简化了,因为HotSpot JVM / GC通常将堆分为具有不同特征的区域。 例如,堆的“ permgen”区域(分配了静态帧和代码块的区域)很少被垃圾收集。

为了补充先前的答案:

  1. 函数存储在特殊区域中,但对它们的引用存储在对象中(对于非静态函数)。
  2. 对静态函数的引用存储在另一个区域中(您可以认为它们存储在静态字段旁边)(静态存储区)。
  3. 所有对象都存储在堆(对象池)中,但是对它们的引用位置有所不同,局部变量在堆栈中,非静态字段存储在对象本身中,因此它们也存储在堆中。
  4. 静态引用放置在内存的另一个特殊部分中(尽管它们是对对象的引用,但它们指向堆)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM