iOS内存总结

1,553 阅读1分钟

RAM(Random Access Memory)

物理内存(RAM)与 CPU 一样都是系统中最稀少的资源,也是最有可能产生竞争的资源,应用内存与性能直接相关 - 通常是以牺牲别的应用为代价。 不像 PC 端,iOS 没有交换空间作为备选资源,这就使得内存资源尤为重要。事实上,在 iOS 中就有 Jetsam 机制负责处理系统低 RAM 事件,Jetsam 是一种类似 Linux 的 Out-Of-Memory(Killer) 的机制。

App使用的内存

mach_task_basic_info 结构体存储了 Mach task 的内存使用信息,其中 resident_size 就是应用使用的物理内存大小,virtual_size 是虚拟内存大小。

#define MACH_TASK_BASIC_INFO     20         /* always 64-bit basic info */
struct mach_task_basic_info {
        mach_vm_size_t  virtual_size;       /* virtual memory size (bytes) */
        mach_vm_size_t  resident_size;      /* resident memory size (bytes) */
        mach_vm_size_t  resident_size_max;  /* maximum resident memory size (bytes) */
        time_value_t    user_time;          /* total user run time for
                                               terminated threads */
        time_value_t    system_time;        /* total system run time for
                                               terminated threads */
        policy_t        policy;             /* default policy for new threads */
        integer_t       suspend_count;      /* suspend count for task */
};

task_info API 根据指定的 flavor 类型返回 target_task 的信息。

kern_return_t task_info
(
	task_name_t target_task,
	task_flavor_t flavor,
	task_info_t task_info_out,
	mach_msg_type_number_t *task_info_outCnt
);

获取APP内存使用量

/**
 获取APP内存使用量
 
 @return byte
 */
+ (unsigned long long)getAppRAMUsage {
    
    struct mach_task_basic_info info;
    mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT;
    
    kern_return_t kr = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &count);
    if (kr != KERN_SUCCESS) {
        return 0;
    }
    return info.resident_size;
}

获取系统内存总量

/**
 获取系统内存总量
 
 @return byte
 */
+ (unsigned long long)getSystemRAMTotal {
    return [NSProcessInfo processInfo].physicalMemory;
}

获取当前设备的内存使用情况

+ (CGFloat)getUsedMemory {
    
    size_t length = 0;
    int mib[6] = {0};
    
    int pagesize = 0;
    mib[0] = CTL_HW;
    mib[1] = HW_PAGESIZE;
    length = sizeof(pagesize);
    if (sysctl(mib, 2, &pagesize, &length, NULL, 0) < 0) {
        return 0;
    }
    
    mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
    
    vm_statistics_data_t vmstat;
    
    if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count) != KERN_SUCCESS) {
        return 0;
    }
    
    int wireMem = vmstat.wire_count * pagesize;
    int activeMem = vmstat.active_count * pagesize;
    return wireMem + activeMem;
}