psi機制
#define PSI_PATH_MEMORY "/proc/pressure/memory"
#define PSI_PATH_IO "/proc/pressure/io"
#define PSI_PATH_CPU "/proc/pressure/cpu"
PSI會注冊三個壓力監(jiān)測器诅岩,如果內(nèi)存壓力太大,就會回調(diào)lmkd函數(shù)進行查殺。
lowmemory監(jiān)測
frameworks/base/services/core/jni/com_android_server_am_LowMemDetector.cpp
static jint android_server_am_LowMemDetector_init(JNIEnv*, jobject) {
int epollfd;
int low_psi_fd;
int medium_psi_fd;
int high_psi_fd;
epollfd = epoll_create(PRESSURE_LEVEL_COUNT);
if (epollfd == -1) {
ALOGE("epoll_create failed: %s", strerror(errno));
return -1;
}
low_psi_fd = init_psi_monitor(PSI_SOME, PSI_LOW_STALL_US, PSI_WINDOW_SIZE_US);
if (low_psi_fd < 0 ||
register_psi_monitor(epollfd, low_psi_fd, (void*)PRESSURE_LOW) != 0) {
goto low_fail;
}
---分割線---
[ams構(gòu)造函數(shù)]
mAppProfiler = new AppProfiler(this, BackgroundThread.getHandler().getLooper(),
new LowMemDetector(this));
[LowMemDetector.init]
private native int init();
---分割線---
[frameworks/base/services/core/jni/com_android_server_am_LowMemDetector.cpp]
static const JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"init", "()I", (void*)android_server_am_LowMemDetector_init},
{"waitForPressure", "()I",
(void*)android_server_am_LowMemDetector_waitForPressure},
};
ProcessList-lmkd
// Low Memory Killer Daemon command codes.
// These must be kept in sync with lmk_cmd definitions in lmkd.h
//
// LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
// LMK_PROCPRIO <pid> <uid> <prio>
// LMK_PROCREMOVE <pid>
// LMK_PROCPURGE
// LMK_GETKILLCNT
// LMK_SUBSCRIBE
// LMK_PROCKILL
// LMK_UPDATE_PROPS
// LMK_KILL_OCCURRED
// LMK_STATE_CHANGED
static final byte LMK_TARGET = 0;
static final byte LMK_PROCPRIO = 1;
static final byte LMK_PROCREMOVE = 2;
static final byte LMK_PROCPURGE = 3;
static final byte LMK_GETKILLCNT = 4;
static final byte LMK_SUBSCRIBE = 5;
static final byte LMK_PROCKILL = 6; // Note: this is an unsolicited command
static final byte LMK_UPDATE_PROPS = 7;
static final byte LMK_KILL_OCCURRED = 8; // Msg to subscribed clients on kill occurred event
static final byte LMK_STATE_CHANGED = 9; // Msg to subscribed clients on state changed
// Low Memory Killer Daemon command codes.
// These must be kept in sync with async_event_type definitions in lmkd.h
//
static final int LMK_ASYNC_EVENT_KILL = 0;
static final int LMK_ASYNC_EVENT_STAT = 1;
// lmkd reconnect delay in msecs
private static final long LMKD_RECONNECT_DELAY_MS = 1000;
將oomadj寫入lmkd模塊
processList向lmkd寫入進程對應(yīng)的oomadj
public static void setOomAdj(int pid, int uid, int amt) {
// This indicates that the process is not started yet and so no need to proceed further.
if (pid <= 0) {
return;
}
if (amt == UNKNOWN_ADJ)
return;
long start = SystemClock.elapsedRealtime();
ByteBuffer buf = ByteBuffer.allocate(4 * 4);
//這里傳遞標記位意思是更新proc的oomadj
buf.putInt(LMK_PROCPRIO);
buf.putInt(pid);
buf.putInt(uid);
buf.putInt(amt);
//通過socket向lmkd發(fā)消息
writeLmkd(buf, null);
long now = SystemClock.elapsedRealtime();
if ((now-start) > 250) {
Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
+ " = " + amt);
}
}
- 向lmkd發(fā)消息更新proc的oomadj
lmkd通過socket接收消息
static void cmd_procprio(LMKD_CTRL_PACKET packet, int field_count, struct ucred *cred) {
// 。廷臼。。省略
snprintf(path, sizeof(path), "/proc/%d/oom_score_adj", params.pid);
---分割線
console:/proc/552 # cat oom_score_adj
-900