Android 如何在内存不足时释放内存,以及如何重新启动它们?
How does Android go about freeing up memory when low, and how does it restart them?
请注意以下词汇,以免混淆
1) 当我说 重新实例化 一个 activity 时,我的意思是 Activity.onCreate(bundle)
2) 当我说 从头开始 和 activity 时,我的意思是 Activity.onCreate(null)
(虽然我不确定这有什么不同)为了这个 post 的目的,请假设我感兴趣的 Android 应用程序都有他们的活动在同一任务中启动
Android 如何从应用程序中释放内存?
假设我有一个 phone。我同时使用了很多应用程序。我厌倦了当前的 Snapchat
应用程序。所以我按下主页按钮并打开 Facebook
。 请注意,我没有按后退按钮,因此 Snapchat
在最近的应用程序概览中继续存在 。
突然由于某种原因 phone 内存非常低,需要开始从后台应用程序中强制释放一些内存。
AndroidOS是否会杀死Snapchat
的一些活动以释放内存
Android OS 是否会终止 Snapchat
的 所有 活动以释放内存
Android 如何管理 "killed" 应用程序?
现在假设我想回到 Snapchat
。我点击了概述按钮,然后从最近使用的应用程序的滚动列表中点击 select Snapchat
。
AndroidOS重新实例化一些活动Snapchat
AndroidOS重新实例化所有活动Snapchat
Android OS 重新实例化 零 活动 Snapchat
并且只是 从头开始 使用初始启动器 activity。
TL;DRD:所有活动都被杀死。
ActivityManagerService
似乎不再杀死任何东西(它只是强制 GC 调用并调度 trim 事件)。
if (false) {
// For now we won't do this; our memory trimming seems
// to be good enough at this point that destroying
// activities causes more harm than good.
if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
&& app != mHomeProcess && app != mPreviousProcess) {
// Need to do this on its own message because the stack may not
// be in a consistent state at this point.
// For these apps we will also finish their activities
// to help them free memory.
mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
}
}
虽然当(如果)它确实试图杀死某些东西时它会杀死后台应用程序的整个进程(它只会调用 kill -9 [PID]
)。由于默认情况下您的所有活动都 运行 在一个 PID 下,当进程终止时,它们都会被销毁。
OOM 和 Low Memory Killers 也是如此 - 两者与进程一起运行并且不区分您的活动。
但是请注意,有些人声称 Android 有时会在内存不足时一项一项地终止特定活动。我没能在 AOSP.
中找到任何证据
==============
现在,关于恢复您的应用程序。我可能不是这里的专家,因为这与 Android 的 "Tasks and Back Stack System" 有关,这比他们的教程视频看起来要复杂得多。
操作从调用 ActivityManager#moveTaskToFront(...)
开始,最终将我们带到 ActivityManagerService#moveTaskToFrontLocked(...)
那里 OS 将尝试检索与您的应用关联的已存储任务记录。如果您的应用程序已被销毁,管理器将不得不转到 ActivityStackSupervisor#restoreRecentTaskLocked(...)
,如果一切顺利,它将找到任务和返回堆栈,并对任务中的每个 activity 执行此操作:
final ArrayList<ActivityRecord> activities = task.mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
mWindowManager.addAppToken(0, r.appToken, task.taskId, stack.mStackId,
r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
r.userId, r.info.configChanges, task.voiceSession != null,
r.mLaunchTaskBehind);
}
当您开始一个新的 activity 时调用相同的方法 (WindowManager#addAppToken(...)
) 并且它带有注释:
// Here it is! Now, if this is not yet visible to the
// user, then just add it without starting; it will
// get started when the user navigates back to it.
所以我的猜测是,当OS恢复一个应用程序时,它会完全重新创建activity堆栈,但实际上只有最顶层的activity实际上会重新启动。我想,设置一个实验来确定我是否就在这里很容易。
=======
又一次更新 :) 是的,这两个方法(ActivityStackSupervisor#resumeTopActivitiesLocked()
和 ActivityStackSupervisor#resumeTopActivityLocked(...)
)稍后会被调用。虽然我真的不理解为什么他们在多个堆栈中恢复活动 - 正如我所说,我绝对不是这里的专家。
请注意以下词汇,以免混淆
1) 当我说 重新实例化 一个 activity 时,我的意思是 Activity.onCreate(bundle)
2) 当我说 从头开始 和 activity 时,我的意思是 Activity.onCreate(null)
(虽然我不确定这有什么不同)为了这个 post 的目的,请假设我感兴趣的 Android 应用程序都有他们的活动在同一任务中启动
Android 如何从应用程序中释放内存?
假设我有一个 phone。我同时使用了很多应用程序。我厌倦了当前的 Snapchat
应用程序。所以我按下主页按钮并打开 Facebook
。 请注意,我没有按后退按钮,因此 Snapchat
在最近的应用程序概览中继续存在 。
突然由于某种原因 phone 内存非常低,需要开始从后台应用程序中强制释放一些内存。
AndroidOS是否会杀死
Snapchat
的一些活动以释放内存Android OS 是否会终止
Snapchat
的 所有 活动以释放内存
Android 如何管理 "killed" 应用程序?
现在假设我想回到 Snapchat
。我点击了概述按钮,然后从最近使用的应用程序的滚动列表中点击 select Snapchat
。
AndroidOS重新实例化一些活动
Snapchat
AndroidOS重新实例化所有活动
Snapchat
Android OS 重新实例化 零 活动
Snapchat
并且只是 从头开始 使用初始启动器 activity。
TL;DRD:所有活动都被杀死。
ActivityManagerService
似乎不再杀死任何东西(它只是强制 GC 调用并调度 trim 事件)。
if (false) {
// For now we won't do this; our memory trimming seems
// to be good enough at this point that destroying
// activities causes more harm than good.
if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
&& app != mHomeProcess && app != mPreviousProcess) {
// Need to do this on its own message because the stack may not
// be in a consistent state at this point.
// For these apps we will also finish their activities
// to help them free memory.
mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
}
}
虽然当(如果)它确实试图杀死某些东西时它会杀死后台应用程序的整个进程(它只会调用 kill -9 [PID]
)。由于默认情况下您的所有活动都 运行 在一个 PID 下,当进程终止时,它们都会被销毁。
OOM 和 Low Memory Killers 也是如此 - 两者与进程一起运行并且不区分您的活动。
但是请注意,有些人声称 Android 有时会在内存不足时一项一项地终止特定活动。我没能在 AOSP.
中找到任何证据==============
现在,关于恢复您的应用程序。我可能不是这里的专家,因为这与 Android 的 "Tasks and Back Stack System" 有关,这比他们的教程视频看起来要复杂得多。
操作从调用 ActivityManager#moveTaskToFront(...)
开始,最终将我们带到 ActivityManagerService#moveTaskToFrontLocked(...)
那里 OS 将尝试检索与您的应用关联的已存储任务记录。如果您的应用程序已被销毁,管理器将不得不转到 ActivityStackSupervisor#restoreRecentTaskLocked(...)
,如果一切顺利,它将找到任务和返回堆栈,并对任务中的每个 activity 执行此操作:
final ArrayList<ActivityRecord> activities = task.mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
mWindowManager.addAppToken(0, r.appToken, task.taskId, stack.mStackId,
r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
r.userId, r.info.configChanges, task.voiceSession != null,
r.mLaunchTaskBehind);
}
当您开始一个新的 activity 时调用相同的方法 (WindowManager#addAppToken(...)
) 并且它带有注释:
// Here it is! Now, if this is not yet visible to the
// user, then just add it without starting; it will
// get started when the user navigates back to it.
所以我的猜测是,当OS恢复一个应用程序时,它会完全重新创建activity堆栈,但实际上只有最顶层的activity实际上会重新启动。我想,设置一个实验来确定我是否就在这里很容易。
=======
又一次更新 :) 是的,这两个方法(ActivityStackSupervisor#resumeTopActivitiesLocked()
和 ActivityStackSupervisor#resumeTopActivityLocked(...)
)稍后会被调用。虽然我真的不理解为什么他们在多个堆栈中恢复活动 - 正如我所说,我绝对不是这里的专家。