
OOM 的全称是 Out-Of-Memory,是由于 iOS 的 Jetsam 机制造成的一种“另类” Crash,它不同于常规的 Crash,通过 Signal 捕获等 Crash 监控方案无法捕获到 OOM 事件。
目前猜测两种情况会造成 OOM,
系统整体内存使用较高,系统基于优先级杀死优先级较低的 App
当前使用的 App 达到了 “high water mark”,也就是达到了系统对单个 App 的内存限制,系统会将你 Kill
XNU 中 opensource.apple.com/source/xnu/… 、opensource.apple.com/source/xnu/… 提供了一些函数和宏,我们可以在 root 权限下使用这些宏和函数来获取当前状态下的所有 App 的 oom 内存阈值,并且基于 PID 甚至可以修改进程的 内存阈值,达到增大 oom内存阈值的效果。
对我们最有用的信息如下:
// 获取进程的 pid、优先级、状态、内存阈值等信息
typedef struct memorystatus_priority_entry {
pid_t pid;
int32_t priority;
uint64_t user_data;
int32_t limit;
uint32_t state;
} memorystatus_priority_entry_t;
// 基于下面这些宏可以达到查询内存阈值等信息,也可以修改内存阈值等
/* Commands */
#define MEMORYSTATUS_CMD_GET_PRIORITY_LIST 1
#define MEMORYSTATUS_CMD_SET_PRIORITY_PROPERTIES 2
#define MEMORYSTATUS_CMD_GET_JETSAM_SNAPSHOT 3
#define MEMORYSTATUS_CMD_GET_PRESSURE_STATUS 4
#define MEMORYSTATUS_CMD_SET_JETSAM_HIGH_WATER_MARK 5 /* Set active memory limit = inactive memory limit, both non-fatal */
#define MEMORYSTATUS_CMD_SET_JETSAM_TASK_LIMIT 6 /* Set active memory limit = inactive memory limit, both fatal */
#define MEMORYSTATUS_CMD_SET_MEMLIMIT_PROPERTIES 7 /* Set memory limits plus attributes independently */
#define MEMORYSTATUS_CMD_GET_MEMLIMIT_PROPERTIES 8 /* Get memory limits plus attributes */
#define MEMORYSTATUS_CMD_PRIVILEGED_LISTENER_ENABLE 9 /* Set the task's status as a privileged listener w.r.t memory notifications */
#define MEMORYSTATUS_CMD_PRIVILEGED_LISTENER_DISABLE 10 /* Reset the task's status as a privileged listener w.r.t memory notifications */
/* Commands that act on a group of processes */
#define MEMORYSTATUS_CMD_GRP_SET_PROPERTIES 100
我们可以创建一个如下代码的程序
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "kern_memorystatus.h"
#define NUM_ENTRIES 1024
char *state_to_text(int State)
{
// Convert kMemoryStatus constants to a textual representation
static char returned[80];
sprintf (returned, "0x%02x ",State);
if (State & kMemorystatusSuspended) strcat(returned,"Suspended,");
if (State & kMemorystatusFrozen) strcat(returned,"Frozen,");
if (State & kMemorystatusWasThawed) strcat(returned,"WasThawed,");
if (State & kMemorystatusTracked) strcat(returned,"Tracked,");
if (State & kMemorystatusSupportsIdleExit) strcat(returned,"IdleExit,");
if (State & kMemorystatusDirty) strcat(returned,"Dirty,");
if (returned[strlen(returned) -1] == ',')
returned[strlen(returned) -1] = '
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/1536/viewspace-2819609/ ,如需转载,请注明出处,否则将追究法律责任。