在MainActivity中,每隔x秒我创建一个新的AsyncTask,并使用new RTask(this).execute(param);
调用execute来异步发送数据到服务器。我认为创建一个新任务经常会导致内存泄漏。因此,当垃圾收集器释放内存时,如何将任务引用设置为null以允许收集它?
我曾尝试在this.cancel(true);
中使用onPostExecute()
但我已经读过,由于Android框架的错误,onpost从未被调用过。任何建议将不胜感激。
由于
答案 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}}。可以从AsyncTask
或doInBackground()
调用它,如果您在AsyncTask
中有一个循环以便停止执行cancel()
,则调用isCancelled()是一个很好的做法{{} 1}}被叫。
答案 1 :(得分:1)
垃圾收集器如何释放AsyncTask分配的内存
就像它为任何其他类释放内存一样。 AsyncTask没有什么特别之处。任务完成后,只要没有其他类引用它,它就会被垃圾收集。将任务引用设置为null将有所帮助。