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++中可能存在