确定iOS设备上的可用RAM量


67

您可能已经看到了许多“系统信息”应用程序,这些应用程序显示诸如剩余电池寿命,甚至是诸如内存等系统信息。

以类似的方式,是否有任何方法可以从我的应用程序中检索当前的可用RAM量,以便我可以更好地决定何时最好转储或保留某些视图以避免内存警告?


3
或者,也许你还没有搜查不够好;-) stackoverflow.com/questions/3823266/...

4
@Bavarious:该问题和其他相关问题的答案在很大程度上没有抓住重点,那就是您可能希望使用更多的RAM来使您的应用程序具有更高的响应度或媒体内容等,但仅在可以舒适地容纳额外内容的设备上加载。“配置文件”和“使用较少的RAM”的建议不会减少它。
马塞洛·坎托斯

@Eric:我遇到了类似的问题,最终自己找到了答案。看这里。请注意,我在寻找系统的总RAM。如果您的要求与我的要求不同,但我希望这会有所帮助。
马塞洛·坎托斯

Answers:


133
#import <mach/mach.h>
#import <mach/mach_host.h>

void print_free_memory ()
{
    mach_port_t host_port;
    mach_msg_type_number_t host_size;
    vm_size_t pagesize;

    host_port = mach_host_self();
    host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
    host_page_size(host_port, &pagesize);        

    vm_statistics_data_t vm_stat;

    if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
        NSLog(@"Failed to fetch vm statistics");
    }

    /* Stats in bytes */ 
    natural_t mem_used = (vm_stat.active_count +
                          vm_stat.inactive_count +
                          vm_stat.wire_count) * pagesize;
    natural_t mem_free = vm_stat.free_count * pagesize;
    natural_t mem_total = mem_used + mem_free;
    NSLog(@"used: %u free: %u total: %u", mem_used, mem_free, mem_total);
}

请注意,此调用不考虑gpu正在使用的内存。如果看到的大小小于预期的系统内存。它比可能分配的图形内存更多。


我是第一个向您提出这一点的人,我感到很震惊。它在我的iPhone上运行良好,对我有很大的帮助!我希望我能给你10分!
David H

我确实找到了另一个可以添加到上面的命令来获取任务统计信息:struct task_basic_info info; if(dump_memory_usage(&info)){fm.resident_size =(size_t)info.resident_size; fm.virtual_size =(size_t)info.virtual_size; }
David H

6
如果要使设备具有总计RAM,只需使用[NSProcessInfo processInfo] .physicalMemory。
史蒂夫·

@Steve,提供计算机上的物理内存量。-(unsigned long long)physicalMemory这如何告诉您应用程序正在使用多少内存?
Nico

1
我认为总内存计算不准确。[NSProcessInfo processInfo].physicalMemory将其与之交叉引用,您会发现后者与该设备的市场内存规格更加一致。
Thomas Elliot

10

这适用于Swift 4。

真正重要的区别是:它在乘法之前强制转换为Int64,因为否则您会很快溢出,特别是如果在使用PC内存的模拟器中运行它。

var pagesize: vm_size_t = 0

let host_port: mach_port_t = mach_host_self()
var host_size: mach_msg_type_number_t = mach_msg_type_number_t(MemoryLayout<vm_statistics_data_t>.stride / MemoryLayout<integer_t>.stride)
host_page_size(host_port, &pagesize)

var vm_stat: vm_statistics = vm_statistics_data_t()
withUnsafeMutablePointer(to: &vm_stat) { (vmStatPointer) -> Void in
    vmStatPointer.withMemoryRebound(to: integer_t.self, capacity: Int(host_size)) {
        if (host_statistics(host_port, HOST_VM_INFO, $0, &host_size) != KERN_SUCCESS) {
            NSLog("Error: Failed to fetch vm statistics")
        }
    }
}

/* Stats in bytes */
let mem_used: Int64 = Int64(vm_stat.active_count +
        vm_stat.inactive_count +
        vm_stat.wire_count) * Int64(pagesize)
let mem_free: Int64 = Int64(vm_stat.free_count) * Int64(pagesize)

2
您好,我尝试了您的示例,但是mem_used的值非常不同。当我将其转换为MB时,它给了我120MB,而在XCode中,它给了我30MB。知道为什么吗?
Mathias Van Houtte '18

谢谢你 只是评论,我认为Int64应该是UInt64。
米诺斯

1
@Minos,我不同意。请记住,2 ^ 63已经是9,223,372,036,854,775,808和Int64的已为整数的优点签署了会小于0时,一些减法不会产生异常

5

您可以检查iOS设备中的可用RAM内存

    #import mach\mach.h
    #import mach\mach_host.h

     static natural_t get_free_memory(void)  
     {  
       mach_port_t host_port;  
       mach_msg_type_number_t host_size;  
       vm_size_t pagesize;  
       host_port = mach_host_self();  
       host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);  
       host_page_size(host_port, &pagesize);  
       vm_statistics_data_t vm_stat;  
       if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS)  
       {  
         NSLog(@"Failed to fetch vm statistics");  
         return 0;  
       }  
       /* Stats in bytes */  
       natural_t mem_free = vm_stat.free_count * pagesize;  
       return mem_free;  
     }  

您知道吗,这是否考虑了GPU使用的内存?
彼得

为什么在mach \ mach.h中加反斜线?
ingconti
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.