【问题标题】:Java (Android) GC Behavour with regards to arrays关于数组的 Java (Android) GC 行为
【发布时间】:2013-08-05 17:46:06
【问题描述】:

我对以下情况有点困惑。

如果有这样创建的数组:

声明:

int[] array1;

实例化:

array1 = new int[500];

但后来,我不再需要 500 个元素,所以我只需创建一个具有新大小的新数组,如下所示:

array1 = new int[50]

访问该数组的代码周围有各种引用,如下所示:

for (x=0;x<array1.length;x++){
array1[x]+someValue
}

其他 450 个元素所在的内存会发生什么变化?数组本身仍然“活着”,不是因为我仍然有很多对其名称的引用,所以它不能被 GC 处理,所以我有点困惑 GC 在这种情况下是如何工作的。

注意我知道我应该使用 arrayList 来重新调整大小,不幸的是,现在这不是我的选择,因为更改我的代码需要大量工作(大小为 18 个班级)所以我想至少在这个项目中坚持使用数组并尽可能地管理它们。

【问题讨论】:

  • “CG”是指“GC”(垃圾收集器)吗?如果不是,我很困惑 - 但如果是这样,您应该编辑问题...
  • 哎呀——是的,当然是 GC——不知道我是怎么输错 3 次的!现在更正了:-)
  • @Zippy 如果你仍然有一个对象的可达引用,它不能被 GC'ed。
  • @ObieMD5 这与那完全不同。实际问题非常不同。

标签: java android memory-management garbage-collection


【解决方案1】:

在您的示例中,您只是在代码执行过程中重复使用变量array1 来引用多个对象。这并不意味着您使用array1 引用的每个对象都将永远保存在内存中。

试着这样想。当您分配 array1 = new int[500] 时,您将在内存中的某处分配大小为 500 的数组,并使用名为 array1 的变量引用该内存块:

稍后,您分配array1 = new int[50],因此array1 现在持有对完全不同对象的引用:

第一个数组有资格进行垃圾回收,因为没有任何东西拥有对它的引用

【讨论】:

  • 不要将array1 本身视为“引用”,将其视为持有引用的变量可能会有所帮助。一开始它持有一个大小为 500 的数组的引用,然后它持有一个完全不同的大小为 50 的数组的引用(此时第一个引用丢失了)。
【解决方案2】:

只要没有引用旧的,旧的就会等待 GC 启动并被收集。使用 new 您将为数组创建一个全新的占位符。

【讨论】:

  • 啊,这就是让我感到困惑的地方——“参考”我假设你的意思是“array1”?由于新数组具有相同的名称,因此代码中到处都有对它的引用(因为我们仍然需要引用它,即使我们现在正在访问新的数组空间)。那么旧的内存空间是否符合 GC 条件?
  • @Zippy GC 将清理所有引用。没什么好担心的。
  • @Zippy 我不认为你有类似 array2 = array1; 的东西。这是一个参考。
  • 不,我没有类似的东西 - 但如果我有会发生什么?如果我想做你所说的 (array2 = array1) 但我现在想做 array2 = (新的) array1 - 这是否意味着即使不再使用旧内存也不会被收集 - 如果你看到了什么我是说?谢谢
  • 如果你这样做,array2 = array1。 array2 的先前引用已准备好进行 GC 处理。正如我所说,您不必担心。
【解决方案3】:

Java 有一种称为垃圾回收的神奇机制,它会重用旧数组的内存并为您分配一个新数组。但是,当您再次调用 new 时,包含 500 个元素的数组的所有原始内容都将丢失。

【讨论】:

  • 嗨@DavidElliman,是的,我只是不确定垃圾收集器在这种情况下是如何工作的,因为如果您明白我的意思,对数组的“引用”仍然存在!所以你是说因为引用现在指向一个新的内存位置,旧内存会自动与这个引用解除关联,从而有资格被收集?这是我认为会发生的事情,但我不太确定,我想避免泄漏:-)
猜你喜欢
  • 2011-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-05
  • 2022-06-15
相关资源
最近更新 更多