计时器导致内存泄漏 [英] Memory leak with Timer

查看:480
本文介绍了计时器导致内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个在监听器事件后取消并重新启动的计时器.一切正常,除了计时器线程泄漏整个外部类.

I am using a timer that is canceled and restarted on a listener event. It all works fine except that the the timer thread leaks the whole outer class.

我的计时器实现如下:

        if(timer != null) {
            timer.cancel();
            timer = null;
            timer = new Timer();
        }
        timer.schedule(new TimerTask() { // Thread leaks!!!!
            @Override
            public void run() {
              mCallback.onHeaderMoving(newToolbarTranslationY );
            }
        } , 150);

我使用MAT分析器来追踪问题并最终解决了问题.我还注释掉了与回调相关的这一行,但是线程仍然泄漏,因此它实际上是计时器本身.但是,我不太了解该代码的问题所在.

I used MAT Analyser to track down the problem and ended up there. I also commented out the line with the callback but the thread still leaks so it is defenetly the timer itself. However I don't really understand what is the problem with that code.

据我从研究中了解到的问题是,匿名内部类(新的Timertask())持有对外部类的引用,因此可能泄漏整个上下文.但是我仍然不明白为什么在线程用完之后(150毫秒后),计时器和对上下文的引用没有被垃圾回收.

As far as I understand from my research the problem is that the anonymous inner class (new Timertask()) holds a reference to the outer class and therefore can leak the whole context. But I still don't understand why the timer and also the reference to the context is not garbage collected after the thread runs out (after 150 ms +).

在这种情况下,即使线程完成后,上下文是否仍不被释放?

Is the context in this case somehow still not released even after the thread finished?

最后我该如何解决此泄漏?我将计时器设置为null,但这并不能解决我的问题.

And finally how do I solve this leak? I set the timer to null but that didn't solved my problem.

修改

 private OnHeaderMovingCallBack mCallback;
 private Timer timer = new Timer();

 //... some other parameters


public ScrollingToolbarManager(View toolbar , View pagerStrip , AbsListView listView , OnHeaderMovingCallBack headerMovingCallBack){
    this.toolbar = toolbar;
    this.pagerStrip = pagerStrip;

    this.listView = listView;

    mCallback = headerMovingCallBack;

    changeStartValues();

}

public static interface OnHeaderMovingCallBack{
    public void onHeaderMoving(int translationY);
}

 public void moveHeader(){

      //... some calculations

    //timer implementation from above
 }

在列表视图的滚动事件上调用

moveHeader()

moveHeader() is called on a scroll event of a listview

推荐答案

如果您认为问题在于匿名内部类持有对外部类的引用,则只需使用静态命名内部类-这将不包含任何内容.参考.将此类内容放入您的班级:

If you think that the problem is that the anonymous inner class holds a reference to the outer class, then simply use a static named inner class - this will hold no reference. Put something like this inside your class:

static class MyTimerTask extends TimerTask {
    private OnHeaderMovingCallBack mCallback;
    int newToolbarTranslationY;

    public MyTimerTask(OnHeaderMovingCallBack mCallback, int newToolbarTranslationY) {
        this.mCallback = mCallback;
        this.newToolbarTranslationY = newToolbarTranslationY;
    }

    @Override
    public void run() {
        mCallback.onHeaderMoving(newToolbarTranslationY);
    }
}

这篇关于计时器导致内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆