首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

iOS Swift 獲取設備可用內存:基於 mach_task_basic_info 實現

     編輯:程式設計疑難解答

需求背景

Swift 中獲取 iPhone/iPad 剩餘可用內存(非 App 佔用內存),用於內存預警、緩存清理策略等場景。

核心 API:mach_task_basic_info

Swift 可直接調用 Darwin 系統調用,與 Objective-C 用法一致。

完整封裝代碼


import Foundation
import MachO // 需在 Build Settings -> Linking -> Other Linker Flags 添加 -lmach

struct MemoryInfo {
    let freeMemory: UInt64      // 空閒內存 (bytes)
    let activeMemory: UInt64    // 活躍內存
    let inactiveMemory: UInt64  // 非活躍內存
    let wiredMemory: UInt64     // 佔用內存
    let totalMemory: UInt64     // 物理總內存
    
    var availableMemory: UInt64 { freeMemory + inactiveMemory }
    var usedMemory: UInt64 { activeMemory + wiredMemory }
}

func getSystemMemoryInfo() -> MemoryInfo? {
    var taskInfo = mach_task_basic_info()
    var count = mach_msg_type_number_t(MemoryLayout.size / MemoryLayout.size)
    
    let kerr = withUnsafeMutablePointer(to: &taskInfo) {
        $0.withMemoryRebound(to: integer_t.self, capacity: Int(count)) {
            task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count)
        }
    }
    
    guard kerr == KERN_SUCCESS else {
        print("task_info 失敗: \(kerr)")
        return nil
    }
    
    // 獲取物理總內存
    var mib: [Int32] = [CTL_HW, HW_MEMSIZE]
    var physicalMemory: UInt64 = 0
    var size = MemoryLayout.size
    sysctl(&mib, 2, &physicalMemory, &size, nil, 0)
    
    return MemoryInfo(
        freeMemory: UInt64(taskInfo.free_count) * UInt64(vm_page_size),
        activeMemory: UInt64(taskInfo.active_count) * UInt64(vm_page_size),
        inactiveMemory: UInt64(taskInfo.inactive_count) * UInt64(vm_page_size),
        wiredMemory: UInt64(taskInfo.wired_count) * UInt64(vm_page_size),
        totalMemory: physicalMemory
    )
}

// 使用示例
if let mem = getSystemMemoryInfo() {
    let formatter = ByteCountFormatter()
    formatter.allowedUnits = [.useGB, .useMB]
    formatter.countStyle = .memory
    
    print("總內存: \(formatter.string(fromByteCount: Int64(mem.totalMemory)))")
    print("可用內存: \(formatter.string(fromByteCount: Int64(mem.availableMemory)))")
    print("已用內存: \(formatter.string(fromByteCount: Int64(mem.usedMemory)))")
}

關鍵點解析

  1. mach_task_basic_info 返回頁面計數,需乘以 vm_page_size (通常 4096/16384 bytes) 換算為字節。
  2. availableMemory = free + inactive:非活躍內存可被系統快速回收重用,屬於可用範圍。
  3. totalMemory 通過 sysctl(HW_MEMSIZE) 獲取物理總內存。
  4. 需在 Target → Build Phases → Link Binary With Libraries 添加 libmach.dylib 或 Linker Flags 添加 -lmach。

對比:獲取 App 自身佔用內存


// 僅獲取當前進程佔用
var info = mach_task_basic_info()
var count = mach_msg_type_number_t(MemoryLayout.size / MemoryLayout.size)
task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), &info, &count)
let residentSize = info.resident_size // 物理駐留內存
let virtualSize = info.virtual_size   // 虛擬內存

注意事項

  • iOS 沙箱限制:無法獲取其他進程詳細內存信息。
  • 系統內存信息僅供參考,實際可用內存受 Jetsam 機制、壓縮內存等影響。
  • 頻繁調用有性能開銷,建議緩存結果或低頻輪詢(如 30 秒一次)。

Swift 直接調用 mach_task_basic_info 即可獲取系統級內存信息,核心邏輯與 Objective-C 完全一致,僅語法適配 Swift 特性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved