Java 中参数的内存分配

Memory Allocation in Java for Parameters

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

myFunction(new MyClass());

谢谢!

Java

共有三组内存
  1. Heap - 这是在调用 new MyClass();
  2. 时创建和定位对象的地方
  3. Stack - 堆栈包含堆栈帧,并且堆栈帧已 space 分配给基元和指向堆中对象的指针。堆栈帧在方法调用时分配,在方法 return
  4. 时释放
  5. 字符串常量: 编译时定义的字符串常量将被添加到一个字符串常量池中。在运行时,可以使用 String.intern()
  6. 将字符串添加到池中

就是这样

在你的例子中分配了两个东西;

  1. 表达式,new MyClass() 在对象堆上分配 MyClass 的一个实例。

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

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

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

Java® Language Specification 没有强制要求有关其工作原理的详细信息。总共只有两个名额:

15.12.4.5. Create Frame, Synchronize, Transfer Control

A method m in some class S has been identified as the one to be invoked.

Now a new activation frame is created, containing the target reference (if any) and the argument values (if any), as well as enough space for the local variables and stack for the method to be invoked and any other bookkeeping information that may be required by the implementation (stack pointer, program counter, reference to previous activation frame, and the like). If there is not sufficient memory available to create such an activation frame, a WhosebugError is thrown.

17.4.1. Shared Variables

Memory that can be shared between threads is called shared memory or heap memory.

All instance fields, static fields, and array elements are stored in heap memory. In this chapter, we use the term variable to refer to both fields and array elements.

Local variables (§14.4), formal method parameters (§8.4.1), and exception handler parameters (§14.20) are never shared between threads and are unaffected by the memory model.

请注意,这是唯一将术语“堆”用作内存类型的地方,以及它是如何实际上在这里定义的……

§15.9.4. Run-Time Evaluation of Class Instance Creation Expressions and §15.10.2. Run-Time Evaluation of Array Creation Expressions 部分更加模糊,说“space 已分配”,如果没有足够的 space 可用,则抛出 OutOfMemoryError,什么都没有更多

所以如果你走区分堆栈和堆的路线,你可以说你的代码 myFunction(new MyClass()); 将导致对 MyClass 实例的堆分配,然后是堆栈分配myFunction 方法实际执行的激活帧。这对任何实际目的都不重要。


如果你想深入了解这个方法,JVM 可能会实现它,你可以参考 Java® Virtual Machine Specification

2.5.2. Java Virtual Machine Stacks

Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread. A Java Virtual Machine stack stores frames (§2.6). A Java Virtual Machine stack is analogous to the stack of a conventional language such as C: it holds local variables and partial results, and plays a part in method invocation and return. Because the Java Virtual Machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java Virtual Machine stack does not need to be contiguous.

2.5.3. Heap

The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.

The heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); objects are never explicitly deallocated. The Java Virtual Machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor's system requirements. The heap may be of a fixed size or may be expanded as required by the computation and may be contracted if a larger heap becomes unnecessary. The memory for the heap does not need to be contiguous

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

当您创建一个新对象时,它通常在堆上分配,但是通过逃逸分析,它可以像局部变量一样解压到堆栈上。

唯一的分配是通过 new 或捕获 lambda(或在极少数情况下的某些本机方法)分配对象的不同方式之间没有任何明确的区别。