獲取iOS設(shè)備的內(nèi)存狀況
由于iPhone這類移動(dòng)設(shè)備內(nèi)存有限,而又不能使用交換區(qū),為了不至于導(dǎo)致內(nèi)存不足而引起運(yùn)行效率降低或應(yīng)用崩潰,有時(shí)候需要獲取當(dāng)前的內(nèi)存狀況,以決定采用的緩存策略。
不過(guò)iOS SDK文檔里并沒(méi)有提及這種底層的API,于是我搜了一番,找到了host_statistics()這個(gè)函數(shù)。
參數(shù)雖然很多,但基本上都是固定的值,我也就不解釋,直接上代碼了:
- #include <mach/mach.h>
- BOOL memoryInfo(vm_statistics_data_t *vmStats) {
- mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
- kern_return_t kernReturn = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)vmStats, &infoCount);
- return kernReturn == KERN_SUCCESS;
- }
- void logMemoryInfo() {
- vm_statistics_data_t vmStats;
- if (memoryInfo(&vmStats)) {
- NSLog(@"free: %u\nactive: %u\ninactive: %u\nwire: %u\nzero fill: %u\nreactivations: %u\npageins: %u\npageouts: %u\nfaults: %u\ncow_faults: %u\nlookups: %u\nhits: %u",
- vmStats.free_count * vm_page_size,
- vmStats.active_count * vm_page_size,
- vmStats.inactive_count * vm_page_size,
- vmStats.wire_count * vm_page_size,
- vmStats.zero_fill_count * vm_page_size,
- vmStats.reactivations * vm_page_size,
- vmStats.pageins * vm_page_size,
- vmStats.pageouts * vm_page_size,
- vmStats.faults,
- vmStats.cow_faults,
- vmStats.lookups,
- vmStats.hits
- );
- }
- }
調(diào)用memoryInfo()就能拿到內(nèi)存信息了,它的類型是vm_statistics_data_t。這個(gè)結(jié)構(gòu)體有很多字段,在logMemoryInfo()中展示了如何獲取它們。注意這些字段大都是頁(yè)面數(shù),要乘以vm_page_size才能拿到字節(jié)數(shù)。
順便再簡(jiǎn)要介紹下:free是空閑內(nèi)存;active是已使用,但可被分頁(yè)的(在iOS中,只有在磁盤上靜態(tài)存在的才能被分頁(yè),例如文件的內(nèi)存映射,而動(dòng)態(tài)分配的內(nèi)存是不能被分頁(yè)的);inactive是不活躍的,實(shí)際上內(nèi)存不足時(shí),你的應(yīng)用就可以搶占這部分內(nèi)存,因此也可看作空閑內(nèi)存;wire就是已使用,且不可被分頁(yè)的。
最后你會(huì)發(fā)現(xiàn),即使把這些全加起來(lái),也比設(shè)備內(nèi)存少很多,那么剩下的只好當(dāng)成已被占用的神秘內(nèi)存了。不過(guò)在模擬器上,這4個(gè)加起來(lái)基本上就是Mac的物理內(nèi)存量了,相差不到2MB。
而總物理內(nèi)存可以用NSRealMemoryAvailable()來(lái)獲取,這個(gè)函數(shù)不需要提供參數(shù),文檔里也有記載,我就不寫演示代碼了。