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

正确的onDestroy()/如何避免内存泄漏

江礼骞
2023-03-14

我读了很多关于如何避免Android内存泄漏的文章,但我仍然不太确定我是否做对了。

  1. 我的应用程序由一个活动组成

问题1:这够了吗?

让我困惑的是,你可以在网上找到一个经典的“不去”的例子(http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on-android/):

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

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

  setContentView(label);
}

我认为,一旦创建完成,标签就超出了范围,并且是GCed。

Q2:这怎么会造成内存泄漏?

我的活动基本上是这样的:

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

    /* Statics */
    AssetUtils.initIndex(this);
    BitmapLoader.startInstance(this);

    /* frame */
    ViewGroup frame = (ViewGroup) getLayoutInflater().inflate(R.layout.frame, null);
    this.setContentView(frame);

    /* create controller */
    Controller controller = new Controller(frame, getLayoutInflater());

    /* START */
    controller.start();
}

@Override
public void onDestroy() {
    super.onStop();

    /* Statics */
    AssetUtils.destroyInstance();
    BitmapLoader.destroyInstance();
}

在控制器内部,我偶尔会使用查看#getContext()检索上下文,将其传递给手动创建的查看等。它从不静态存储在某个地方,只存储在类的成员变量中,这些变量都返回到控制器。

问题3:我是否忽略了什么?

共有1个答案

蓬化
2023-03-14

Q1。你断章取义了(无意开玩笑:)

如果您看到原始文章,泄漏实际上发生在引入位图字段的下一个代码片段中。Roman然后清楚地解释了它泄漏的原因。您展示的代码不会泄漏。

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

问题2:只有在没有其他选择的情况下才使用活动上下文,并且绝不允许在范围大于其引用的活动范围的内容中引用活动上下文。据我所知,您显示的代码没有泄漏,因为没有任何内容引用的作用域大于您的活动。你怀疑是吗?

当使用位图、静态引用或非静态引用时,我习惯于从onPause()中的视图中解除位图的绑定(请记住,onDestroy()不能保证,但它有点无关紧要,就像你正在被破坏一样,你的进程被终止了,所以GC不成问题)。链接的文章还解释了如何做到这一点。我已将其作为处理位图的任何活动的模板模式。

[编辑]

对不起,我刚查过。本文没有说明如何解除绑定。以下是我使用的模式:

@Override
protected void onPause()
{
        super.onPause();

        unbindDrawables(findViewById(R.id.mainLayout));
        System.gc();
}


@Override
protected void onDestroy()
{
        super.onDestroy();

        unbindDrawables(findViewById(R.id.mainLayout));
        System.gc();
}

private void unbindDrawables(View view)
{
        if (view.getBackground() != null)
        {
                view.getBackground().setCallback(null);
        }
        if (view instanceof ViewGroup && !(view instanceof AdapterView))
        {
                for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++)
                {
                        unbindDrawables(((ViewGroup) view).getChildAt(i));
                }
                ((ViewGroup) view).removeAllViews();
        }
}

主布局是活动布局的根视图。

我包括onDestroy(),因为我可能会手动()完成我的活动。

笔记呼叫系统。gc()是一个复杂的主题,您可能希望省略它。这里有一些很好的讨论,为什么这可能不是一件好事,主要是关于性能。然而,在我看来,当一个活动被销毁时,暗示现在是执行GC的好时机不会有什么坏处。不必要地调用它的低效性将在销毁活动的日常开支中消失。

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

  • 本文向大家介绍如何避免SAP B1 DI API中的内存泄漏,包括了如何避免SAP B1 DI API中的内存泄漏的使用技巧和注意事项,需要的朋友参考一下 经验法则是这样的,如果实例化DI API对象,则必须释放它。如果不明确释放它,则将导致内存泄漏。 您可以使用ReleaseComObject方法来释放对象内存。如果您尝试释放一个空对象,它将抛出异常。 因此,最好在尝试释放对象之前进行null检

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

  • 我是android开发的新手,我刚刚从以下链接读到了Romain Guy的“避免android内存泄漏” http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on-android/ 然后我在我的android模拟器上用他著名的代码片段做了一个小测试 此代码应该在更改方向时泄漏第一个活动上下文。因此,我在emulator中运行了

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

  • 手动创建vue组件的方法: 手动销毁组件的方法 在组件销毁后,仍然能检测到大量的detached DOM,检测过没有全局的事件绑定,有哪位大佬遇到过类似的问题,望不吝赐教!