垃圾收集器如何释放AsyncTask分配的内存

时间:2013-03-21 10:43:27

标签: android memory android-asynctask

在MainActivity中,每隔x秒我创建一个新的AsyncTask,并使用new RTask(this).execute(param);调用execute来异步发送数据到服务器。我认为创建一个新任务经常会导致内存泄漏。因此,当垃圾收集器释放内存时,如何将任务引用设置为null以允许收集它? 我曾尝试在this.cancel(true);中使用onPostExecute()但我已经读过,由于Android框架的错误,onpost从未被调用过。任何建议将不胜感激。

由于

2 个答案:

答案 0 :(得分:5)

实际上,AsyncTask回收不应该存在任何问题,除非您从param对其进行任何引用或在doInBackground()内生成内存泄漏。

所以,你可能会想,如果你正在创建许多长时间运行的AsyncTasks,那么它会导致一些内存问题。实际上它不是真的(至少在最新的Android版本上)。 AsyncTask source code显示

  • 它使用单例有界执行程序:

    private static final int CORE_POOL_SIZE = 5;
    private static final int MAXIMUM_POOL_SIZE = 128;
    private static final int KEEP_ALIVE = 1;
    
    public static final Executor THREAD_POOL_EXECUTOR
        = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
    

    这意味着执行者不会同时运行超过128个AsyncTasks(根据我的理解,128不是很大)。

  • 它对Executor使用有界查询:

    private static final BlockingQueue<Runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<Runnable>(10);
    

因此,基于以上几点,同一时间创建和运行的数量AsyncTasks是有限的而不是那么大。因此,如果AsyncTask中的代码没有创建任何内存泄漏,那么根据我的理解,没有问题。同时Android不允许您使用AsyncTasks自行发送垃圾邮件。 Checkout ThreadPoolExecutors description以熟悉它管理内存的方式(如果您担心同时创建的线程太多)。

特别是在你的情况下,我不认为在前一个请求尚未完成时(在类似请求的情况下)对服务器执行另一个请求是个好主意,也没有必要执行许多频繁的小请求 - 在这种情况下,您的应用会过快地吸取电池。

关于cancel()来电,基于Android documentation for AsyncTask

  

取消任务

     

可以通过调用cancel(boolean)随时取消任务。   调用此方法将导致后续调用isCancelled()   返回true。在调用此方法之后,改为onCancelled(Object)   之后将调用onPostExecute(Object)   doInBackground(Object [])返回。确保取消任务   你应该尽快检查返回值   如果可能的话,定期从doInBackground(Object [])获取isCancelled()   (例如在循环内部。)

所以,我不确定你的意思是“我试图使用this.cancel(true);在onPostExecute()中”而cancel()如果从{{onPostExecute()调用则无关1}}。可以从AsyncTaskdoInBackground()调用它,如果您在AsyncTask中有一个循环以便停止执行cancel(),则调用isCancelled()是一个很好的做法{{} 1}}被叫。

答案 1 :(得分:1)

  

垃圾收集器如何释放AsyncTask分配的内存

就像它为任何其他类释放内存一样。 AsyncTask没有什么特别之处。任务完成后,只要没有其他类引用它,它就会被垃圾收集。将任务引用设置为null将有所帮助。