java - Android 线程分配 - 不断增长的堆?

标签 java android multithreading heap-memory

大家好,

我正在开发一个针对 API 7 的 Android 应用程序,其中我使用了一个需要重新启动的 Activity 。假设我的 Activity 如下所示:

public class AllocActivity extends Activity implements OnClickListener{

    Button but;
    private Handler hand = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_alloc);

        but = (Button) findViewById(R.id.button);
        but.setText("RELOAD");
        but.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0){
                Intent intent = getIntent();
                startActivity(intent);
                finish();
            }
        });  
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        System.gc();
    }

    /****** THREADS AND RUNNABLES ******/

    final Runnable fullAnim = new Thread(new Runnable(){
        @Override
        public void run(){
            try{
                hand.post(anim1);
                Thread.sleep(2000);
                hand.post(anim2);
                Thread.sleep(1000);
                // and so on
            }catch(InterruptedException ie){ie.printStackTrace();}
        }
    });

    final Runnable anim1 = new Runnable() {
        @Override
        public void run(){
            // non-static method findViewById
            ImageView sky = (ImageView)findViewById(R.id.sky);
        }
    };
}

问题是 gc 似乎没有释放 fullAnim 线程,因此每次重新启动时堆都会增长约 100K - 直到速度减慢并崩溃。将 fullAnim 声明为静态确实解决了这个问题 - 但当我使用非静态引用时,这对我来说不起作用。

所以在这一点上我有点迷失了 - 我希望你能建议我下一步该去哪里。我可能做错了什么,或者是否有一个工具可以用来管理线程在重新启动后删除和释放堆。

亲切的问候

更新

感谢所有回答的人 - 提供了很多帮助。使用 TimerTask 最终成功了。我做了以下更改:

/****** THREADS AND RUNNABLES ******/

final TimerTask fullAnim = new TimerTask(){
    @Override
    public void run(){
        try{
            hand.post(anim1);
            Thread.sleep(2000);
            hand.post(anim2);
            Thread.sleep(1000);
            // and so on
        }catch(InterruptedException ie){ie.printStackTrace();}
    }
};

由于 Activity 长度超过 6k loc,这是一个相当不错的解决方案,而且不会面临更大的影响。荣誉!

我不使用计时器来安排任务 - 不知道这是否是不好的做法,但是 动画的调用方式如下:

Thread t = new Thread(fullAnim);
t.start();

最佳答案

  • 正在运行的线程永远不会被垃圾回收。
  • 如果您的Activity停止或被销毁,线程不会自动停止。它可以永远运行。
  • 每个非静态内部类都保留对封闭实例的引用。例如。 hand.post(anim1); 在该内部类中工作,因为它具有对 AllocActivity.this 的隐式引用。

因此,您有效要做的就是保持对 Activity 的引用的存活时间超过其应有的存活时间,即直到 onDestroy 之后。

确保stop threads如果您不再需要它们,请手动进行。

关于java - Android 线程分配 - 不断增长的堆?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18415951/

相关文章:

c++ - 使用boost::thread的Actor计算模型

java - 立即显示 Activity 而不是显示通知

android - 升级Intercom SDK会导致一堆 “Error:(6) Error retrieving parent for item: No resource found that matches the given name”错误

android - 滑动开始时,向上滑动面板完全打开。

c++ - posix 线程同步停止在同一代码

python - 多线程模式下的 aiosqlite 和 SQLite 有什么区别?

java - 在 Java 中实现自己的 List、Stack、Queue 或其他数据结构的原因

java - 在 Java Streams 中按范围分组

java - 如何在 solr 中提交完全导入之前获取文档编号?

java - 如何在Android中创建像Real Calc一样的科学计算器?