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

标签 android memory android-asynctask

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

谢谢

最佳答案

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

因此,您可能会想,如果您正在创建许多长时间运行的 AsyncTask,那么它会导致一些内存问题。实际上它不是真的(至少在最新的 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 个 AsyncTask(根据我的理解,128 个不是很大)。

  • 它为执行器使用有界查询:

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

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

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

关于 cancel() 调用,基于 Android documentation for AsyncTask :

Cancelling a task

A task can be cancelled at any time by invoking cancel(boolean). Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns. To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.)

所以,我不确定您的意思是“我尝试在 onPostExecute() 中使用 this.cancel(true);”,而 cancel() 与此无关如果从 onPostExecute() 调用。它可以从 AsyncTaskdoInBackground() 调用,最好调用 isCancelled()如果您在 AsyncTask 中有一个循环,以便在 cancel() 调用后停止执行。

关于android - 垃圾收集器如何释放 AsyncTask 分配的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15545255/

相关文章:

java - 在各种平台上创建文件的常见位置(非用户特定)

java.lang.RuntimeException : Unable to start activity ComponentInfo{. ..} : java. lang.NullPointerException

iphone - 为什么在调试过程中会收到有关从远程iOS设备读取Xcode框架文件的警告?

java - 等待 setOnItemClickListener 中的变量更改

c# - Android - 异步任务问题

android - 自定义通知布局不覆盖整个宽度

iOS AssetLibrary 存储指针

ios - iOS 游戏中的大量内容

android - Android 中 BroadcastReceiver 中的 AsyncTask 在死线程错误上向处理程序发送消息

java - 如何使警报对话框中的复选框左对齐?