android中内存泄漏的逻辑

时间:2014-02-04 08:41:51

标签: android memory

通常在c ++中,内存泄漏是什么,如果我们分配了像

这样的对象

Obj c = new Obj();

然后我们做

c = b; (example)

我们丢失了指向内存泄漏的对象c的指针。

问题:

但是在android垃圾收集器中,当没有指向它们的指针时收集对象。那么为什么甚至在那之后就会出现内存泄漏?

更新

所有答案都指向保留对未使用对象的引用导致内存泄漏。那就对了。但这是内存泄漏的唯一原因。除非是静态的,否则在活动结束时将释放保持指针。有位图和其他内存饥饿对象,它们不会导致任何问题

5 个答案:

答案 0 :(得分:1)

在垃圾回收运行时中,内存泄漏意味着即使不再使用对象也无法收集对象。例如,引用保留在对象上,但引用不再用于任何内容。

通常,术语内存泄漏用于指这些不可收集的对象不断累积的情况,增加分配的堆大小并最终导致OOM。

答案 1 :(得分:1)

在Android / Java中发生内存泄漏

  • 即使在不再需要对象/实例的引用之后也是如此。

  • 完成后,
  • 打开文件流

  • 未公开连接

内存泄漏还有其他原因,但这些是most common ones

答案 2 :(得分:1)

我认为我们首先需要定义“内存泄漏”。内存泄漏是你不再需要的东西,但它仍然在内存中,每次创建一个新对象时,都会在内存中分配一个新的位置。应用程序将及时保存越来越多的内存。

private static Drawable background;

@Override
protected void onCreate(Bundle state) {
  super.onCreate(state);

  TextView label = new TextView(this);

  background = getDrawable(R.drawable.large_bitmap);

  label.setBackgroundDrawable(background);

  setContentView(label);
}

上面的示例,TextView将Activity作为引用,这是

之间的链接

TextView 活动

现在,然后有一个静态变量

背景

保存背景drawable,静态变量将一直存活,直到应用程序被销毁或完成。想象一下,你想破坏活动,当你破坏静态变量时仍然会保存一个活动链接,因为垃圾收集器将无法收集它。

您可以查看here了解更多内容。

答案 3 :(得分:1)

当任何可以引用它的助手类保留Context(活动,服务等)时,可能会发生泄漏。

插图:而不是:

public class Helper {

    private static Context mContext;

    public Helper(Context context){

        mContext = context;
    }

    public static void methodDoesSomething(){

        ...
    }
}

通过将其作为参数传递来使用上下文而不保留它:

public class Helper {

    public static void methodDoesSomething(Context context){
        ...
    }
}

因为Android在某些时候想要销毁一个Activity,并且一个对象有一个对它的引用,所以垃圾收集器无法删除该Activity,因此我们有内存泄漏。

答案 4 :(得分:1)

答案部分在你的问题中:正是因为那些引用没有被释放。假设你有一个类实例的情况,你已经结束了它的工作但是在某些情况下,实例会保持一个它没有被释放的状态。此外,垃圾收集器无法释放它,如果不加以控制,如果不处理,内存量甚至可能会增加。

还有一件事。您可能拥有一个看起来正确且写得很好的代码,但是当您实例化一些本机库时,这意味着您正在引用类的层次结构。如果你不知道你在做什么,你可能会错误地处理一些引用并导致内存泄漏。一个非常流行的示例是在您的班级中保留Context引用。永远不会释放上下文实例,这是内存泄漏的原因。

除此之外,还有明显的解决方案(完成后可以使用免费对象等)。在Java中有SoftReferencesWeakReferences和其他。这个对象是告诉垃圾收集器它们在未使用时被释放的优先级或者没有其他引用指向它们的容器。因此,您正在帮助GC了解应该释放的内容。它们在Android环境中的某个点上是危险的,因为应用程序的堆数限制为16MB,因此WeakReference可能收集得太快。有必要检查对象是否仍然存在。