Java中参数的内存分配

Java中参数的内存分配,java,jvm,language-lawyer,jvm-bytecode,Java,Jvm,Language Lawyer,Jvm Bytecode,下面语句中的数据是存储为自动内存分配还是动态内存分配,或者两者都存储 myFunction(new MyClass()); 谢谢大家! Java中有三组内存 Heap-这是调用new MyClass()时创建和定位对象的地方 堆栈-堆栈包含堆栈帧,堆栈帧为基本体和指向堆中对象的指针分配了空间。堆栈帧在方法调用时分配,在方法返回时解除分配 字符串常量:编译时定义的字符串文本将添加到字符串常量池中。在运行时,可以使用String.intern()将字符串添加到池中 就是这样在您的示例中分配了两件事

下面语句中的数据是存储为自动内存分配还是动态内存分配,或者两者都存储

myFunction(new MyClass());

谢谢大家!

Java中有三组内存

  • Heap-这是调用new MyClass()时创建和定位对象的地方
  • 堆栈-堆栈包含堆栈帧,堆栈帧为基本体和指向堆中对象的指针分配了空间。堆栈帧在方法调用时分配,在方法返回时解除分配
  • 字符串常量:编译时定义的字符串文本将添加到字符串常量池中。在运行时,可以使用String.intern()将字符串添加到池中

  • 就是这样

    在您的示例中分配了两件事

  • 表达式
    new MyClass()
    在对象堆上分配
    MyClass
    的实例

  • new
    表达式的结果是对象引用。对象引用保存在激活记录中,用于调用
    myFunction()
    。激活记录在调用线程的调用堆栈上分配


  • 术语“自动内存分配”和“动态内存分配”在Java上下文中没有任何意义。在Java中,所有内存都由执行环境管理

    在其他编程语言中,术语“自动存储”和“动态存储”用于区分超出范围时自动释放的存储和需要应用程序执行显式释放操作的存储。在Java中,根本没有显式的释放。您会发现人们和文献继续区分堆栈和堆,其中只有后者包含对象,其生存期可能超过创建它们的方法的执行时间。然而,这只是一种逻辑分离,可能无法反映特定JVM实现的实际工作方式

    政府并没有要求提供关于该系统工作原理的太多细节。只有两个点:

    某些类
    S
    中的方法
    m
    已被标识为要调用的方法

    现在,将创建一个新的激活框架,其中包含目标引用(如果有)和参数值(如果有),以及足够的空间用于本地变量和堆栈,以便调用方法以及实现可能需要的任何其他簿记信息(堆栈指针、程序计数器、对上一个激活帧的引用等)。如果没有足够的内存来创建这样一个激活帧,则抛出
    stackoverflowerrror

    可以在线程之间共享的内存称为共享内存或堆内存

    所有实例字段、
    static
    字段和数组元素都存储在堆内存中。在本章中,我们使用术语变量来表示字段和数组元素

    局部变量(§14.4)、形式方法参数(§8.4.1)和异常处理程序参数(§14.20)从不在线程之间共享,并且不受内存模型的影响

    请注意,这是唯一一个将术语“heap”用作内存类型的地方,以及它在这里的实际定义方式

    部分和更为模糊,表示“已分配空间”,如果没有足够的可用空间,则抛出
    OutOfMemoryError
    ,仅此而已

    因此,如果您采用区分堆栈和堆的方法,您可以说您的代码
    myFunction(newmyclass());
    将导致对
    MyClass
    的实例进行堆分配,然后对
    myFunction
    方法的实际实现的激活框架进行堆栈分配。这与任何实际目的无关


    如果您想更深入地了解这种方式,JVM可以实现它,您可以参考:

    每个Java虚拟机线程都有一个私有Java虚拟机堆栈,与线程同时创建。Java虚拟机堆栈存储帧(§2.6).Java虚拟机堆栈类似于传统语言(如C)的堆栈:它保存局部变量和部分结果,并在方法调用和返回中发挥作用。由于Java虚拟机堆栈除了推送和弹出帧之外从不直接操作,因此可以对帧进行堆分配。Java虚拟机堆栈的内存l机器堆栈不需要是连续的

    Java虚拟机有一个在所有Java虚拟机线程之间共享的堆。堆是运行时数据区域,所有类实例和数组的内存都是从该区域分配的

    堆是在虚拟机启动时创建的。对象的堆存储由自动存储管理系统(称为垃圾收集器)回收;对象从不显式解除分配。Java虚拟机不采用特定类型的自动存储管理系统,并且可以根据实施者的系统要求选择存储管理技术。堆可以是固定大小,也可以根据计算需要进行扩展,如果更大的堆变得不必要。堆的内存不需要是连续的


    请注意,这些定义仅在用途上有所不同,而在约束上却没有显著差异,即可能是固定大小或可调整大小的,也可能是连续的或不连续的,更不用说明确提到在堆上分配堆栈帧的可能性了。

    创建新对象时,它通常是在然而,通过escape分析,它可以像局部变量一样解压到堆栈上

    唯一的分配是通过
    new
    或捕获lambda(或某些本地meth