【问题标题】:Android non-static inner class memory issueAndroid非静态内部类内存问题
【发布时间】:2015-07-16 11:15:30
【问题描述】:

我在我的一个适配器中编写了以下类。该类从其构造函数中的活动中获取视图:

    private class ContactViewHolder {
       public TextView tvPrimary;
       public TextView tvSecondary;
       public ImageView imageViewCheck;


       public ContactViewHolder(View v) {
           this.tvPrimary = (TextView) v.findViewById(R.id.tv_primary);
           this.imageViewCheck = (ImageView) v.findViewById(R.id.iv_check);
           v.findViewById(R.id.iv_mm_user);
           this.tvSecondary = (TextView) v.findViewById(R.id.tv_secondary);
       }
   }

这会导致内存泄漏问题吗? 似乎它可能会导致内存泄漏,如this link 中所述,关于一个稍微不同的问题。

所以,总而言之,我想知道:

  1. 这会导致内存泄漏问题吗?
  2. 如果是这样,为什么?

【问题讨论】:

  • 只要不是静态的,应该没问题
  • 如果您的外部类之外的其他人持有对它的引用,您的内部类(除非是静态的)会将您的外部类保留在 RAM 中。

标签: android memory-leaks inner-classes non-static


【解决方案1】:

如果你这样定义一个实例:

static ContactViewHolder  holder = new ContactViewHolder(view);

这会导致内存泄漏。

如果你定义一个非静态实例,它没有内存泄漏。

泄漏原因如下:

非静态内部类将持有外部类实例的引用,因此静态持有者将持有适配器的引用。 众所周知,静态实例不能被GC收集,它是一个gc root,所以直到进程终止才能收集你的适配器。

【讨论】:

    【解决方案2】:

    当您不知道/控制内部类对象的生命周期时,就会发生内存泄漏。因为它没有被 GC 收集,所以持有他的对象不会被收集等等,这会导致内存泄漏。基本上,如果您的持有人只像您写的那样以最简单的方式处理用户界面,那么他不可能“超过”持有他的适配器,那么它就不会导致内存泄漏。

    如果由于某种原因您在 Holder 中实现 onClick 侦听器,例如打开 AsyncTask,那么您无法控制对象的生命周期,因为它会打开一个新线程,并且可能在适配器不再存在时执行某些操作在 UI 上,这将导致内存泄漏。

    结论: 非常了解您的对象的生命周期以及谁拥有它们。

    【讨论】:

      猜你喜欢
      • 2013-11-04
      • 1970-01-01
      • 2013-07-05
      • 1970-01-01
      • 2015-09-25
      • 1970-01-01
      • 2011-09-01
      • 1970-01-01
      • 2016-01-26
      相关资源
      最近更新 更多