【问题标题】:Using local stack variable outside scope in java [duplicate]在java中使用范围外的本地堆栈变量[重复]
【发布时间】:2018-02-15 12:23:08
【问题描述】:

以下代码在 Java 中是否安全?我的担心是因为在函数 f() 中,变量 arr 是在堆栈上分配的,因此在离开作用域时会被释放,但仍会在作用域之外被引用。

public class Main {

public static class Array {
    public final int[] arr;

    public Array(int arr[]) {
        this.arr = arr;
    }
}

public static Array f() {
    int arr[] = {1, 2, 3};
    return new Array(arr);
}

public static void main(String[] args) {
    Array a = f();
    System.out.println(a.arr[0]);
    System.out.println(a.arr[1]);
    System.out.println(a.arr[2]);
 }
}

【问题讨论】:

  • arr 变量的生命周期在 f 结束时结束,但 数组 的生命周期与变量的生命周期是分开的。
  • 您不必担心 Java 中的内存管理。如果你习惯 C++,想想智能指针。
  • 但是Array 变量存储的不是生命周期结束的变量的引用吗?
  • 没有。它存储对数组的引用,而不是变量。在 Java 中不能引用变量。
  • 或者您可能正在寻找这个:Does initialized java array go onto stack or heap?

标签: java stack


【解决方案1】:

在 f 中,您创建变量 arr,它是一个 int 数组,然后构造一个 Array 对象,该对象最终具有指向同一个原始 int 数组的指针。

函数 f 然后结束返回 Array 对象 - 变量 arr 超出范围,但它指向的内存位置仍被返回的 Array 对象引用,因此内存位置不能被垃圾回收。然后将返回值分配给您的 main 方法的变量 a ,这意味着 arr 最初指向的内存在 main 方法结束之前仍然不能被垃圾收集。这可以从最初称为 arr 的值作为 main 函数的一部分输出这一事实来证明

简短的回答,是的,这样做是安全的。当没有任何东西指向它/不再引用它时,内存将被垃圾收集

【讨论】:

    【解决方案2】:

    这是安全的,因为 java 使用引用来跟踪它。即使 arr 超出 f 的范围,数据仍然被 a 引用。垃圾收集器也不会在分配返回值所需的时间内清理它。

    附带说明,尽量避免使用相同的名称作为局部变量和字段。

    【讨论】:

      猜你喜欢
      • 2019-11-16
      • 1970-01-01
      • 2020-12-14
      • 2012-03-04
      • 1970-01-01
      • 2020-07-31
      • 1970-01-01
      • 1970-01-01
      • 2012-08-09
      相关资源
      最近更新 更多