#ios #unity/日常积累 ios相关逻辑 头文件: ## MemoryInfoPlugin.h ``` objc #import @interface MemoryInfoPlugin : NSObject + (NSString *)getMemoryInfo; + (double)getUsedMemoryMB; + (double)getTotalMemoryMB; + (double)getMemoryUsagePercentage; @end ``` ## MemoryInfoPlugin.mm ``` objc #import "MemoryInfoPlugin.h" #import #import @implementation MemoryInfoPlugin + (NSString *)getMemoryInfo { double used = [self getUsedMemoryMB]; double total = [self getTotalMemoryMB]; double percentage = [self getMemoryUsagePercentage]; return [NSString stringWithFormat:@"已使用: %.2f MB, 总共: %.2f MB, 使用率: %.2f%%", used, total, percentage]; } + (double)getUsedMemoryMB { task_vm_info_data_t taskInfo; mach_msg_type_number_t infoCount = TASK_VM_INFO_COUNT; kern_return_t kernReturn = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&taskInfo, &infoCount); if (kernReturn != KERN_SUCCESS) { return -1.0; } return (double)taskInfo.phys_footprint / 1024.0 / 1024.0; } + (double)getTotalMemoryMB { int64_t memorySize = 0; size_t size = sizeof(memorySize); sysctlbyname("hw.memsize", &memorySize, &size, NULL, 0); return (double)memorySize / 1024.0 / 1024.0; } + (double)getMemoryUsagePercentage { double used = [self getUsedMemoryMB]; double total = [self getTotalMemoryMB]; if (total > 0) { return (used / total) * 100.0; } return -1.0; } // 为Unity导出C函数 extern "C" { const char* _GetMemoryInfo() { NSString *info = [MemoryInfoPlugin getMemoryInfo]; return strdup([info UTF8String]); } double _GetUsedMemoryMB() { return [MemoryInfoPlugin getUsedMemoryMB]; } double _GetTotalMemoryMB() { return [MemoryInfoPlugin getTotalMemoryMB]; } double _GetMemoryUsagePercentage() { return [MemoryInfoPlugin getMemoryUsagePercentage]; } } @end ``` 调用 测试用例 ## IOSMemoryInfo.cs ``` cs using System.Runtime.InteropServices; using UnityEngine; public class IOSMemoryInfo : MonoBehaviour { #if UNITY_IOS && !UNITY_EDITOR [DllImport("__Internal")] private static extern string _GetMemoryInfo(); [DllImport("__Internal")] private static extern double _GetUsedMemoryMB(); [DllImport("__Internal")] private static extern double _GetTotalMemoryMB(); [DllImport("__Internal")] private static extern double _GetMemoryUsagePercentage(); #endif // 获取完整内存信息字符串 public static string GetMemoryInfo() { #if UNITY_IOS && !UNITY_EDITOR return _GetMemoryInfo(); #else return "仅支持iOS设备"; #endif } // 获取已使用内存(MB) public static double GetUsedMemoryMB() { #if UNITY_IOS && !UNITY_EDITOR return _GetUsedMemoryMB(); #else return -1; #endif } // 获取总内存(MB) public static double GetTotalMemoryMB() { #if UNITY_IOS && !UNITY_EDITOR return _GetTotalMemoryMB(); #else return -1; #endif } // 获取内存使用百分比 public static double GetMemoryUsagePercentage() { #if UNITY_IOS && !UNITY_EDITOR return _GetMemoryUsagePercentage(); #else return -1; #endif } // 使用示例 void Start() { InvokeRepeating("ShowMemoryInfo", 1.0f, 5.0f); } void ShowMemoryInfo() { Debug.Log("内存信息: " + GetMemoryInfo()); Debug.Log("已使用: " + GetUsedMemoryMB() + " MB"); Debug.Log("总内存: " + GetTotalMemoryMB() + " MB"); Debug.Log("使用率: " + GetMemoryUsagePercentage() + "%"); } } ``` 相关目录结构: ![[Pasted image 20250326153420.png]] ![[Pasted image 20250326153443.png]] 最终xcode运行效果: ![[Pasted image 20250326153542.png]] ## 相关逻辑解析 这个获取iOS内存占用的方法有效,主要基于以下几个关键点: 1. Mach API的使用: ``` task_info(mach_task_self(), TASK_VM_INFO, ...) ``` 这是iOS/macOS底层Mach内核提供的API,可以直接访问进程的内存信息。Mach是XNU内核的核心组件,专门负责内存管理等基础服务。 2. phys_footprint字段: ``` taskInfo.phys_footprint ``` 这是Apple在iOS 9+引入的专用字段,表示: - 实际物理内存使用量(非虚拟内存) - 包含压缩内存(Compressed Memory) - 包含IOKit使用的内存 - 符合Xcode Memory Report的统计标准 3. 与系统监控的一致性: 这个数值与Xcode Debug Gauges显示的内存值完全一致,是Apple官方推荐的内存统计方式。相比过时的resident_size字段,phys_footprint能更准确地反映真实内存使用情况。 4. 权限处理: ``` mach_task_self() ``` 通过获取当前进程的task端口,避免了越权访问的问题,符合iOS的沙盒安全机制。 5. 单位转换: ``` / 1024.0 / 1024.0 ``` 将字节转换为MB的经典处理方式(1MB = 1024KB = 10241024B) 需要注意的版本适配: - phys_footprint在iOS 9.0+可用 - 如果需支持更老版本,需要添加条件编译: ``` cpp #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0 return taskInfo.phys_footprint; #else return taskInfo.internal + taskInfo.compressed; #endif ``` 这个实现方式是目前iOS平台最准确可靠的内存统计方案,被主流性能监控工具广泛采用。 也可配合[[xcode性能检测工具]]确认性能数据,是否准确