Swift 中獲取 iPhone/iPad 剩餘可用內存(非 App 佔用內存),用於內存預警、緩存清理策略等場景。
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)))")
}
mach_task_basic_info 返回頁面計數,需乘以 vm_page_size (通常 4096/16384 bytes) 換算為字節。availableMemory = free + inactive:非活躍內存可被系統快速回收重用,屬於可用範圍。totalMemory 通過 sysctl(HW_MEMSIZE) 獲取物理總內存。libmach.dylib 或 Linker Flags 添加 -lmach。
// 僅獲取當前進程佔用
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 // 虛擬內存
Swift 直接調用 mach_task_basic_info 即可獲取系統級內存信息,核心邏輯與 Objective-C 完全一致,僅語法適配 Swift 特性。