Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.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/3/android/213.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
Java 处理器内存泄漏?_Java_Android_Memory Leaks - Fatal编程技术网

Java 处理器内存泄漏?

Java 处理器内存泄漏?,java,android,memory-leaks,Java,Android,Memory Leaks,我有一个在主线程上声明的处理程序: mainHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: Bundle bundle = msg.getData();

我有一个在主线程上声明的处理程序:

  mainHandler = new Handler() {

            @Override
            public void handleMessage(Message msg) {

                switch (msg.what) {

                    case 1:

                        Bundle bundle = msg.getData();
                        mTextView.setText(bundle.getString("message"));
                        break;

                    . . .

                    default:
                        super.handleMessage(msg);
                        break;
                }
            }
        };
其中mTextView是在create()上定义的文本视图

我有一个单独线程中使用的任务。runnable从主线程存储
mainHandler
,并告诉它发送消息:

public class SomeRunnable implements Runnable {

    private Handler mHandler;

    public SomeRunnable(Handler handler) throws IOException {
        . . .    
        mHandler = handler;
    }

    @Override
    public void run() {

        while (!Thread.currentThread().isInterrupted()) {
            try {
                    . . .

                    Message msg = mHandler.obtainMessage();
                    . . .
                    mHandler.sendMessage(msg);
                }

            } catch (IOException e) {
                Log.e("Error", e.hashCode() + ": " + e.getLocalizedMessage());
            }
        }
    }
我已经看到,如果处理程序类不是静态的,那么使用
Handler#postDelayed()
等方法可能会造成内存泄漏。但是,我使用的是
处理程序#sendMessage()
,它可以立即将消息放入消息队列

我仍然有内存泄漏的危险吗?即使:

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

        mThread.interrupt();
        mainHandler.removeCallbacksAndMessages(null);
    }

谢谢大家!

为了解决所有可能发生的情况,您可以将
mHandler
a
WeakReference
设置为如下所示:

public class SomeRunnable implements Runnable {

    private WeakReference<Handler> mHandlerRef;

    public SomeRunnable(Handler handler) throws IOException {
        . . .    
        mHandlerRef = new WeakReference<Handler>( handler );
    }

    @Override
    public void run() {

        while (!Thread.currentThread().isInterrupted()) {
            try {
                    . . .
                    Handler mHandler = mHandlerRef.get();
                    if( mHandler != null ) {
                        Message msg = mHandler.obtainMessage();
                        . . .
                        mHandler.sendMessage(msg);
                    }
                }

            } catch (IOException e) {
                Log.e("Error", e.hashCode() + ": " + e.getLocalizedMessage());
            }
        }
    }
}
public类SomeRunnable实现Runnable{
私人WeakReference mHandlerRef;
公共SomeRunnable(处理程序)引发IOException{
. . .    
mHandlerRef=新的WeakReference(处理程序);
}
@凌驾
公开募捐{
而(!Thread.currentThread().isInterrupted()){
试一试{
. . .
Handler mHandler=mHandlerRef.get();
if(mHandler!=null){
Message msg=mHandler.obtainMessage();
. . .
mHandler.sendMessage(msg);
}
}
}捕获(IOE异常){
Log.e(“Error”,e.hashCode()+”:“+e.getLocalizedMessage());
}
}
}
}

您发布的代码不清楚,但是您的
处理程序
可运行
是否包含对非瞬态对象的引用?此外,与您似乎所说的相反,我希望
静态
ly-hold
处理程序
比我上面看到的更容易发生内存泄漏。@323go我的可运行“SomeRunnable”与主线程中的处理程序“mainHandler”具有相同的地址。这就是你所定义的非暂时性吗?我的处理程序不包含任何引用,尽管它引用了主线程中的TextView。为了安全起见,您可以引用
mainHandler
a
WeakReference
。扎克,另一种方法是,如果您使用的是
Eclipse
,则使用
Eclipse内存分析器。查看
应用程序是否泄漏内存,使用该工具还可以确定导致程序泄漏的原因。看@Mike我今天早上刚下载了这个。谢谢你的建议。我一定会尝试一下,分析一下记忆。我只是想问一下,从概念上讲,我的实现是否存在潜在的内存泄漏。谢谢你的建议!我将看看这对我的应用程序有何影响,我会让您知道我的最终解决方案;每次在while循环内调用,还是可以在循环外执行?这取决于您在循环中做了多少工作,或者您是否让位于循环中的其他线程。
运行
将在发布后很快执行;使用
WeakReference
唯一有帮助的情况是,如果您有一个长时间运行的
Runnable
,您希望它能够干净地中断/中止。Runnable在一个单独的线程中执行,并一直持续到应用程序终止。然后您一定要调用
get()
在使用它之前,引用的
处理程序可能已经不存在了。如果它返回
null
,这也是停止线程执行的信号。