Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/186.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
android内存泄漏背后的逻辑 通常在C++中,如果我们分配了一个像这样的对象,那么内存泄漏是什么呢?_Android_Memory - Fatal编程技术网

android内存泄漏背后的逻辑 通常在C++中,如果我们分配了一个像这样的对象,那么内存泄漏是什么呢?

android内存泄漏背后的逻辑 通常在C++中,如果我们分配了一个像这样的对象,那么内存泄漏是什么呢?,android,memory,Android,Memory,Obj c=new Obj() 如果我们这样做了 c=b;(示例) 我们丢失了指向对象c的指针,这就是内存泄漏 问题: 但在android中,垃圾收集器在并没有指向它们的指针时收集对象。那么为什么在那之后还会出现内存泄漏呢 更新 所有的答案都指向保留对未使用对象的引用会导致内存泄漏。没错。但这是导致内存泄漏的唯一原因。保持指针将在活动完成时释放,除非它是静态的。存在位图和其他内存不足对象,它们不会在这方面造成任何问题吗?在垃圾收集的运行时中,内存泄漏意味着对象即使不再使用也无法收集。例如,引用保

Obj c=new Obj()

如果我们这样做了

c=b;(示例)

我们丢失了指向对象
c
的指针,这就是内存泄漏

问题:

但在android中,垃圾收集器在并没有指向它们的指针时收集对象。那么为什么在那之后还会出现内存泄漏呢

更新


所有的答案都指向保留对未使用对象的引用会导致内存泄漏。没错。但这是导致内存泄漏的唯一原因。保持指针将在活动完成时释放,除非它是静态的。存在位图和其他内存不足对象,它们不会在这方面造成任何问题吗?

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


无意中,术语内存泄漏是指这些无法收集的对象不断累积、增加分配的堆大小并最终导致OOM的情况。

在Android/Java中,内存泄漏会发生

  • 当您保留对象/实例的引用时,即使不再需要该引用

  • 当您保持打开一个文件流时,当您处理完它时

  • 未关闭的连接

内存泄漏还有其他原因,但这些是最常见的原因,我认为我们首先需要定义“内存泄漏”。内存泄漏是您不再需要的东西,但它仍在内存中,每次创建新对象时,都会在内存中分配一个新位置。应用程序将及时保存越来越多的内存

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获取活动作为引用,它是

文本视图活动

现在,有一个静态变量

背景

它保存后台可绘制的静态变量,直到应用程序被销毁或完成为止。假设您想要销毁活动,当您销毁静态变量时,它仍然会保留一个指向活动的链接,因为垃圾收集器将无法收集它


您可以查看更多信息。

当上下文(活动、服务等)被任何有引用的帮助器类保留时,可能会发生泄漏

插图:与此相反:

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会在某个时候销毁某个活动,例如,某个对象有一个对它的引用,所以垃圾收集器无法删除该活动,因此我们存在内存泄漏。

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

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


除了显而易见的(完成后释放对象等)之外,还有一些解决方案。Java中有
软引用
软引用
,以及其他。这些对象是容器,它们告诉垃圾收集器,一旦未使用它们,它们会优先被释放,或者没有其他指向它们的引用。所以你在帮助GC知道应该释放什么。在Android环境中,它们在某一点上是危险的,因为应用程序的堆限制太大,所以
WeakReference
可能收集得太快。有必要检查对象是否仍然存在。

。还有关于内存管理的讨论,最后是关于内存泄漏以及如何使用mat工具的讨论一旦对象超出范围,它将被垃圾收集。如果其他人引用此类对象,则会发生内存泄漏,主要是静态字段如果实例变量较少,则无法处理。强引用不指向内存泄漏(术语为泄漏未保留)。但我经常听到“记忆泄漏”这个词。一些更了解的人可以解释这一点,我很想知道。静态变量的作用域始终在应用程序中,这不会导致任何内存泄漏。是吗?但它将在程序结束或进程停止时发布。那么这个术语就不同了,为什么是内存泄漏呢。谢谢你的帮助,我想我们首先需要定义“内存泄漏”。内存泄漏是你不再需要的东西,但它仍然在内存中,每次你创建一个新的活动时,内存也会在内存中保存一个新的活动。在上面的例子中,你破坏了活动,这意味着你不想让它出现在你的记忆中,但它仍然存在,你实际上持有一个不应该存在的记忆。这应该是内存泄漏的定义。在您的示例中,GC已经从堆中收集了c值,这实际上并没有导致任何内存泄漏。是的,保留引用是内存泄漏,但可以通过使用低范围对象来减少。但是还有其他因素导致内存泄漏,因为我们不能直接释放内存,因为C++中可能存在