【问题标题】:How to avoid memory leaks when using arraylist with for each?将arraylist与for each一起使用时如何避免内存泄漏?
【发布时间】:2017-10-24 02:34:03
【问题描述】:
private ArrayList<OutputInputPair> pairs = new ArrayList<OutputInputPair>();
public void process() {
    while (!stopped) {
        for (OutputInputPair pair : pairs) {
            processCommandPairs(pair);
        }
    }
}

首先当用户点击停止按钮时,stopped = true 所以,如果用户没有点击按钮, 总是执行processCommandPairs 方法。

点击停止按钮时

@Override
public void stop() {
    Log.d(TAG, "STOP memory leak");
    pairs.clear();
    pairs = null;
    stopped = true;
}

我只有一个问题,如果用户不点击按钮,数组列表发生内存泄漏对吗?

如果不是,如何避免arraylist上的内存泄漏?

谢谢。 enter image description here

【问题讨论】:

  • 我不能 100% 确定您在做什么,但您似乎在与事件驱动的编程范式作斗争。
  • @HovercraftFullOfEels process() 方法只执行,记录开始。当我停止按钮单击时,arraylist 部分不会发生内存泄漏

标签: java android arraylist memory-leaks


【解决方案1】:

覆盖您的活动的onDestroy 方法并将stopped 显式设置为true,以便在您的活动关闭时退出while循环并且ArrayList将可用于垃圾回收。

【讨论】:

  • 谢谢,那么,如果我的activity没有关闭,发生内存泄漏是不是?
  • 如果它存储在 RAM 中,即使你不再需要它,你也可以告诉它内存泄漏。所以当你不再需要它的时候,你可以将stopped设置为true,这样就不会发生内存泄漏了。
【解决方案2】:

关于您的问题: “我只有一​​个问题,如果用户不点击按钮,数组列表发生内存泄漏对吗?”

答案是“不。这不对”

但我知道它确实会在您的代码中发生。并且导致内存泄漏以及for-each循环,基本上有3种情况组合在一起(需要避免):

  1. 使用 for-each 循环而不是简单的 for-循环
  2. for-each 循环嵌套在一个无限循环中(例如while(true){...}
  3. for-each 循环循环遍历一个集合(例如 ArrayList)而不是一个数组

在这些情况下会引发内存泄漏,因为在运行hasNext()next() 或内部类Itr 内部的其他方法之前,将执行以下拼凑的代码(您可以在 ArrayList 类中查看)

@NotNull public Iterator<E> iterator() {
    return new Itr();
}

由于这段代码在无限循环中被调用,Itr 的无限实例将被创建并最终导致内存泄漏。

【讨论】:

    【解决方案3】:

    在 Android 中使用 Wea​​kReference 与在普通的旧 Java 中使用 Wea​​kReference 没有任何不同。这是一个很好的指南,给出了详细的解释:https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references

    您应该考虑在需要引用对象时使用一个,但您不希望该引用保护对象免受垃圾收集器的影响。一个典型的例子是当内存使用率过高时您希望被垃圾回收的缓存(通常使用 Wea​​kHashMap 实现)。

    【讨论】:

      猜你喜欢
      • 2010-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-13
      • 1970-01-01
      • 2012-10-22
      相关资源
      最近更新 更多