1

In the MainActivity, every x seconds I create a new AsyncTask and I call execute with new RTask(this).execute(param); to send data to a server asyncronously. I think that create a new task so often can cause memory leaks. So when garbage collector release the memory and how can I set the task reference to null to allow to collect it? I've tried to use this.cancel(true); within onPostExecute() but I've read that, due to a bug of the Android framework, onpost is never called. Any suggestion will be greatly appreciated.

Thanks

4

2 回答 2

5

实际上,回收不应该有任何问题,AsyncTask除非您持有对它的任何引用param或在内部产生内存泄漏doInBackground()

所以,您可能会想,如果您要创建许多长时间运行的 AsyncTask,那么它会导致一些内存问题。实际上这不是真的(至少在最新的 Android 版本上)。AsyncTask 源代码表明

  • 它使用单例有界执行器:

    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. 查看ThreadPoolExecutors 描述以熟悉它管理内存的方式(如果您担心同时创建的线程过多)。

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

关于cancel()调用,基于AsyncTask 的 Android 文档

取消任务

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

所以,我不确定你的意思是“我试图在 onPostExecute() 中使用 this.cancel(true);”,而cancel()如果从onPostExecute(). 可以从AsyncTask或从调用它,如果你有一个循环,调用isCancelled()doInBackground()是一个很好的做法,以便在调用后停止它的执行。AsyncTaskcancel()

于 2013-03-21T11:45:24.510 回答
1

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

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

于 2013-03-21T12:11:47.253 回答