iOS如何获取当前内存使用情况swift版

在使用GPU将训练出来的模型运行iOS时,发现对于稍微大一点的图片,内存会存在暴增问题。严重时出现了闪退。因此需要监控SDK在工作时的内存实时消耗情况。在使用iOS监控资源时,查询相关资料,不过大都是OC版本的,其实有涉及到很多C语言方面的语法转换,在转换的时候遇到了不少问题,如提示:Cannot convert value of type 'mach_task_basic_info' to type 'integer_t' (aka 'Int32') in coercion。查询了很多资料并结合此篇文章,给出swift版本:

代码:

    func report_memory()->ApplicationMemoryCurrentUsage {
        var info = mach_task_basic_info()
        var count = mach_msg_type_number_t(MemoryLayout<mach_task_basic_info>.size)/4
        
        let kerr: kern_return_t = withUnsafeMutablePointer(to: &info) {
            $0.withMemoryRebound(to: integer_t.self, capacity: 1) {
                task_info(mach_task_self_,
                          task_flavor_t(MACH_TASK_BASIC_INFO),
                          $0,
                          &count)
            }
        }
        
        if kerr == KERN_SUCCESS {
            
            print("Memory in use (in bytes): \(info.resident_size)")
            let usage = info.resident_size / (1024 * 1024)
            let total = ProcessInfo.processInfo.physicalMemory / (1024 * 1024)
            let ratio = Double(info.virtual_size) / Double(ProcessInfo.processInfo.physicalMemory)
            return ApplicationMemoryCurrentUsage(usage: Double(usage), total: Double(total), ratio: Double(ratio))
        }
        else {
            print("Error with task_info(): " +
                (String(cString: mach_error_string(kerr), encoding: String.Encoding.ascii) ?? "unknown error"))
            return ApplicationMemoryCurrentUsage()
        }

其中的ApplicationMemoryCurrentUsage是一个结构体,其结构体内部分别代表着已用内存,总内存,和占用比例。而1024*1024是从MB->KB->B的转换,结构体具体为:

struct ApplicationMemoryCurrentUsage{
    
    var usage : Double = 0.0
    var total : Double = 0.0
    var ratio : Double = 0.0
    
}

本以为以上的代码会解决实际问题,但是最终运行并对比Xcode自带的memory检测工具来看,差别太大。特别是最后发现ratio有时候会大于1,最终检查发现,给出的内存数据是虚拟数据,这代表不了实际的物理内存。具体的iOS内存分配问题感觉此篇文章解释的还算不错。

那么如何给出物理内存的使用情况的,通过查找文章发现:vm_statistice_data_t()函数控制着整体系统上物理内存信息。最终代码如下,ApplicationMemoryCurrentUsage结构体我稍作了一下改动。

    func getUsedMemory()->ApplicationMemoryCurrentUsage {
        var applicationUseageMemory = ApplicationMemoryCurrentUsage.init()
        var usedMemory: Int64 = 0
        let hostPort: 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)
        var pagesize:vm_size_t = 0
        host_page_size(hostPort, &pagesize)
        var vmStat: vm_statistics = vm_statistics_data_t()
        let status: kern_return_t = withUnsafeMutableBytes(of: &vmStat) {
            let boundPtr = $0.baseAddress?.bindMemory(to: Int32.self, capacity: MemoryLayout.size(ofValue: vmStat) / MemoryLayout<Int32>.stride)
            return host_statistics(hostPort, HOST_VM_INFO, boundPtr, &host_size)
        }
        if status == KERN_SUCCESS {

            usedMemory = (Int64)((vm_size_t)(vmStat.active_count + vmStat.inactive_count + vmStat.wire_count) * pagesize)
            let total = (Int64)(ProcessInfo.processInfo.physicalMemory)
            applicationUseageMemory.usageMemory = usedMemory
            applicationUseageMemory.freeMemory = (Int64)(total) - usedMemory
            applicationUseageMemory.usedRatio = (Double)(usedMemory) / (Double)(total)
            return applicationUseageMemory
        }
        else {
            print("Failed to get Virtual memory inforor")
            return applicationUseageMemory
        }
    }
通过运行并对比Xcode自带的内存检测工具发现,数据相差很少。由于对iOS的内存分配掌握的还不够充足,有一些问题还有待解决,比如说kern_reture_t有个free_count属性,但是通过(Int64)(total) - usedMemory 语句计算出来的值和直接通过free_return_t.free_count得到的相差300M左右的数据。欢迎各位大神补充相关方面的知识。





猜你喜欢

转载自blog.csdn.net/qq26983255/article/details/80765788