当前位置: 首页 > 知识库问答 >
问题:

关于Romain Guy的避免Android内存泄漏

彭洲
2023-03-14

我是android开发的新手,我刚刚从以下链接读到了Romain Guy的“避免android内存泄漏”

http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on-android/

然后我在我的android模拟器上用他著名的代码片段做了一个小测试

private static Drawable drawable;

private StringBuilder sb;

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

    TextView label = new TextView(this);
    label.setText("Leaks are bad");

    if (drawable == null) {
        drawable = getResources().getDrawable(R.drawable.ic_launcher);
    }

    sb = new StringBuilder();

    for (int i = 0; i < 1024; i++) {
        sb.append('a');
    }

    label.setCompoundDrawables(null, drawable, null, null);

    setContentView(label);
}

此代码应该在更改方向时泄漏第一个活动上下文。因此,我在emulator中运行了该程序,并更改了方向一次(我还打印了2个活动上下文ca.welcomelm.leaktest)。MainActivity@45f81f98和ca.welcomelm。泄漏测试。MainActivity@45f8d6f8 ). 然后我转储HPROF并通过传入的引用char[]跳转到列出对象。我想我应该看到2个字符[]的模式是“aaaaaaaaaaaa…”,由这2个活动上下文引用。但我发誓我只看到了第二个上下文引用的一个。泄漏的上下文不存在。我认为这是GCed。其他人能证实这一点吗?谢谢

共有2个答案

田嘉澍
2023-03-14

没错,一旦drawable释放对TextView的引用,原始TextView及其引用的对象(上下文、活动等)将被GC'ed。当添加标签时,会发生释放。setCompoundDrawables()(在@user3375547的示例中)或标签。setBackgroundDrawable()(在Romain Guy的原始示例中)被调用

但是,Context被泄露了一段时间,因为Drawable保留了对TextView的引用时间过长,从而阻止了以前的Context(和所有其他引用的对象)在可能的情况下被GC'ed。

现在,想象一下Android没有创建活动的另一个实例的情况。例如,用户退出了活动。Android此时可能会销毁活动。在这种情况下,静态引用仍然存在并阻止上下文被GC'ed,从而导致泄漏。GC只会在活动被重新创建、应用程序进程被终止或Classloader被GC'ed时发生,正如@uDevel在下面的评论中提到的那样。

毛德曜
2023-03-14

更改:

if (drawable == null) {
        drawable = getResources().getDrawable(R.drawable.ic_launcher);
}

例如:

if (drawable == null)
        drawable = getResources().getDrawable(R.drawable.ic_launcher);
else
        Log.i("blablabla", "Drawable initialized in prior activity");

然后开始进行屏幕旋转。您会注意到Log. i将启动,因为绘图对象被标记为静态并且已经在之前的活动中初始化。这是内存泄漏开始的点。

由于现代设备的内存资源非常丰富,因此您不会轻易注意到此类泄漏。然而,如果您的应用程序包含大量这样的引用,或者运行在低端设备上,那么您可能很幸运很快就能阻止内存泄漏。

 类似资料:
  • 本文向大家介绍避免 Android中Context引起的内存泄露,包括了避免 Android中Context引起的内存泄露的使用技巧和注意事项,需要的朋友参考一下 Context是我们在编写Android程序经常使用到的对象,意思为上下文对象。 常用的有Activity的Context还是有Application的Context。Activity用来展示活动界面,包含了很多的视图,而视图又含有图片

  • 问题内容: 所以我有这个C ++程序,它是通过Java程序中的JNI调用的,代码如下: 在倒数第二行中,从不释放而是返回,是否会导致最终的内存泄漏?反正有解决这个问题的方法吗? 还有可能不是返回字符串而是返回布尔值(由LogonUser函数返回),而不是jstring,而是添加了要在方法中传递的“ errormessage”引用,并更新了它?我的Java程序能否看到“ errormessage”的

  • 我在SupportMapFragmet上阅读了这篇文档,它说: 从GoogleMap获得的任何对象都与视图相关联。重要的是不要持有超出视图生命周期的对象(例如标记)。否则会导致内存泄漏,因为视图无法释放。 我对此有点困惑,因为没有办法修改,除非您持有它们的引用,就像这里的许多问题所说的那样(像这样和这样)......所以我错过了什么吗? 我目前正在使用哈希映射将我的标记与其他对象关联起来,我看不出

  • 问题内容: 有关关闭Java中数据库连接的后续问题 我知道conn.close()是必需的,但不知道为什么。一旦方法调用结束,垃圾收集器是否会释放连接对象(并释放连接对象中存储的所有指向数据库的处理程序)? 问题答案: 一旦方法调用结束,垃圾收集器是否会释放连接对象(并释放连接对象中存储的所有指向数据库的处理程序)? 没有。JDBC驱动程序保留对连接的引用,因此除非您可以关闭(),否则它不会被清除

  • 问题内容: 有效的Java说: 内存泄漏的第三个常见来源是侦听器和其他回调。如果在客户端注册回调但未显式注销的情况下实现API,除非您采取某些措施,否则它们会累积。确保回调被及时垃圾回收的最佳方法是仅存储对其的弱引用,例如,通过仅将它们作为键存储在WeakHashMap中。 我是Java的初学者。有人可以教我如何在回调中创建弱引用,并告诉我它们如何解决内存泄漏问题吗?谢谢。 问题答案: 阅读这篇文

  • 我读了很多关于如何避免Android内存泄漏的文章,但我仍然不太确定我是否做对了。 我的应用程序由一个活动组成 问题1:这够了吗? 让我困惑的是,你可以在网上找到一个经典的“不去”的例子(http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on-android/): 我认为,一旦创建完成, 检索上下文,将其传递给手动创建的查看