AsyncTask内存泄漏

4
创建类似于asyncTask的异步任务
AsyncTask<Void,Void,Void> newTask = new AsyncTask<Void,Void,Void>{
....
}
newTask.execute()

如何创建内存泄漏?

2个回答

4

好的,@sherays,特别是在您的情况下,如果您在上一个请求尚未完成时执行另一个请求到服务器(在类似请求的情况下),这将导致内存泄漏的风险。

实际上,除非您从参数中保留任何对它的引用或在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并不算很大)。

执行器使用有界查询(bounded query):

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

因此,根据上述观点,创建和同时运行的AsyncTasks数量是有限制的,不会很大。因此,如果您在AsyncTask内部的代码没有创建任何内存泄漏,则根据我的理解就没有问题。同时,Android也不会让您用AsyncTasks来垃圾邮件自己。查看 ThreadPoolExecutors 的描述以了解它管理内存的方式(如果您担心同时创建了太多线程)。

所以,如果您仍然面临内存泄漏问题,请取消任务:

关于调用cancel(),根据Android AsyncTask文档:

取消任务

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


0

是的:在调用onPostExecute后,您的线程是否被垃圾回收或仍然在内存中?

异步任务不会在活动被解除时立即取消或销毁。如果您的线程比较轻量级并且在短时间内完成,只需让它继续运行,并在onPostExecuteMethod中添加一个yourActivity.this.isFinishing()子句。


1
但是,this.isFinishing() 只会返回活动是否即将结束。我的活动在 onPostExecute() 之后并没有结束,只是 UI 从服务器更新了新数据。 - shreyas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接