当前位置: 首页 > 面试题库 >

这个Runnable可以防止内存泄漏吗?

姜玮
2023-03-14
问题内容

我在Java中的总的初学者和已经创建了一个简单的Java的Android片断其中一个Runnable 1,5秒钟后,我改变TextViewHello WorldHola Mundo。它工作正常,基本上WeakReference应该防止这种内存泄漏发生吗?我怀疑在发生设备定向时是否绝对没有内存泄漏。我很乐意对此进行检查,但无法在模拟的Android中更改方向。

这是代码:

package com.example.helloworld;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
import android.util.Log;
import java.lang.ref.WeakReference;

public class HelloWorldActivity extends Activity
{
    private Handler h = new Handler();
    private static TextView txtview;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        txtview = (TextView) findViewById(R.id.mainview);

        h.postDelayed(new WeakRunnable(txtview),1500);
    }

    private static final class WeakRunnable implements Runnable {
        private final WeakReference<TextView> mtextview;

        protected WeakRunnable(TextView textview){
            mtextview = new WeakReference<TextView>(textview);
        }

            @Override
            public void run() {
                TextView textview = mtextview.get();
                if (textview != null) {
                    txtview.setText("Hola Mundo");
                    textview = null; // No idea if setting to null afterwards is a good idea
                }
                Log.d("com.example.helloworld", "" + textview);
            }
    }

}

编辑

它可以防止内存泄漏,但也有一些答案与UI线程阻塞有关。实际上,此代码在主(UI)线程中运行处理程序。要产生一个新线程,我要手动产生一个线程,如下所示:

package com.example.helloworld;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
import android.util.Log;
import java.lang.ref.WeakReference;

public class HelloWorldActivity extends Activity
{

    private static TextView txtview;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        txtview = (TextView) findViewById(R.id.mainview);

        Thread t = new Thread(new WeakRunnable(txtview));
        t.start();
    }

    private static final class WeakRunnable implements Runnable {
        private final WeakReference<TextView> mtextview;

        protected WeakRunnable(TextView textview){
            mtextview = new WeakReference<TextView>(textview);
        }

            @Override
            public void run() {
                TextView textview = mtextview.get();
                if (textview != null) {
                    /*
                    try {
                        Thread.sleep(1500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    */
                    txtview.setText("Hola Mundo");
                    textview = null;
                }
                Log.d("com.example.helloworld", "" + Thread.currentThread().getName()); // Outputs "Thread-<num>" if not running on UI thread
            }
    }

}

现在的问题是,我似乎无法以任何方式延迟生成的线程,否则它将起作用。

这个:

try {
    Thread.sleep(1500);
} catch (InterruptedException e) {
    e.printStackTrace();
}

使应用本身退出,我不明白为什么。某事告诉我,我以错误的方式延迟了它。

编辑2

感谢@EugenMatynov给我的链接:从android中的另一个线程更新ui,我理解了为什么退出该应用程序。归结为 您不能从主线程以外的线程调用UI方法 的原因
并且从另一个线程更新UI是一种不好的做法。


问题答案:

我认为如果您使用以下代码,则代码不会泄漏:

private static Handler h = new Handler();

要么

txtview.postDelayed(new WeakRunnable(txtview),1500);

因为您已将视图存储为WeakReference。方法:

txtview.postDelayed(new WeakRunnable(txtview),1500);

只需调用UI线程的主处理程序即可,因此,如果活动被破坏,则视图为null,并且可运行项不添加任何内容。

同样由于缺乏参考,该活动可以被垃圾回收,因为没有强大的参考。



 类似资料:
  • 问题内容: 我正在设计一个Web应用程序,该应用程序旨在显示一堆使用AJAX定期更新的数据。一般的使用场景是用户将整天保持打开状态,然后不时浏览一下。 我遇到的问题是浏览器的内存占用量随时间缓慢增长。Firefox和IE 7(尽管不是Chrome)都在发生这种情况。几个小时后,它可能导致IE7占用约200MB的内存,而FF3导致占用约400MB的内存。 经过大量测试,我发现只有在响应AJAX调用时

  • 问题内容: 我们知道node.js为我们提供了强大的功能,但强大的功能带来了巨大的责任。 据我所知,V8引擎不进行任何垃圾收集。因此,我们应该避免什么最常见的错误,以确保没有内存从节点服务器泄漏。 编辑: 对不起,V8确实具有强大的垃圾收集器。 问题答案: 据我所知,V8引擎不进行任何垃圾收集。 V8内置了强大而智能的垃圾收集器。 您的主要问题是不了解闭包如何维护对外部函数的范围和上下文的引用。这

  • 我正在使用org.AsynchTtpClient发布异步请求。 在关闭tomcat时,我得到了以下日志: 严重:web应用程序[/test]似乎启动了一个名为[pool-1-thread-1]的线程,但未能停止它。这很有可能造成内存泄漏。 2017年7月4日10:53:00 AM org.apache.catalina.loader.webappclassloaderbase clearRefer

  • 我的模板如下所示 现在,当我试图在注释字段“今天的天气预报是”中使用以下字符串构建模板时,velocity最终将其呈现为 我如何防止它逃脱我的角色?

  • 我是一个相当新的观察和根据这篇文章。下面的示例会泄漏内存。然而,我在网上看到了大量的教程展示了这样的例子。 可观察性的一般最佳实践是什么?

  • 问题内容: 我认为我的android应用正在泄漏内存。我不是绝对确定这是问题所在。 应用程序打开时经常崩溃,并且logcat尝试加载位图图像时会显示“内存不足”异常。 崩溃后,我重新打开了该应用程序,它运行正常。Logcat会显示许多“ gc”,并且JIT表会不时地向上调整大小,而不会向下调整,直到应用程序因内存不足错误而崩溃。 这听起来像是内存泄漏吗?如果是这样,我该如何定位和关闭泄漏点。 这是