以编程方式检索iPhone上的内存使用情况
我试图检索我的iPhone应用程序在任何时候,以编程方式使用的内存量。 是的,我知道关于ObjectAlloc /泄漏。 我对这些不感兴趣,只知道是否可以编写一些代码并获取正在使用的字节数量并通过NSLog报告。
谢谢。
要获取应用程序正在使用的内存的实际字节数,可以执行下面的示例。 但是,您应该熟悉各种性能分析工具,以及它们旨在为您提供更好的总体使用情况。
#import <mach/mach.h> // ... void report_memory(void) { struct task_basic_info info; mach_msg_type_number_t size = sizeof(info); kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size); if( kerr == KERN_SUCCESS ) { NSLog(@"Memory in use (in bytes): %lu", info.resident_size); NSLog(@"Memory in use (in MB): %f", ((CGFloat)info.resident_size / 1000000)); } else { NSLog(@"Error with task_info(): %s", mach_error_string(kerr)); } }
在结构info.virtual_size中还有一个字段,它将为您提供可用虚拟内存(或在任何情况下作为潜在虚拟内存分配给您的应用程序的内存)的字节数。 pgb链接的代码将为您提供设备可用的内存量以及它是什么types的内存。
TASK_BASIC_INFO
的标题说:
/* Don't use this, use MACH_TASK_BASIC_INFO instead */
这是一个使用MACH_TASK_BASIC_INFO
的版本:
void report_memory(void) { struct mach_task_basic_info info; mach_msg_type_number_t size = MACH_TASK_BASIC_INFO_COUNT; kern_return_t kerr = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &size); if( kerr == KERN_SUCCESS ) { NSLog(@"Memory in use (in bytes): %u", info.resident_size); } else { NSLog(@"Error with task_info(): %s", mach_error_string(kerr)); } }
这里是report_memory()增强,以迅速显示NSLog()中的泄漏状态。
void report_memory(void) { static unsigned last_resident_size=0; static unsigned greatest = 0; static unsigned last_greatest = 0; struct task_basic_info info; mach_msg_type_number_t size = sizeof(info); kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size); if( kerr == KERN_SUCCESS ) { int diff = (int)info.resident_size - (int)last_resident_size; unsigned latest = info.resident_size; if( latest > greatest ) greatest = latest; // track greatest mem usage int greatest_diff = greatest - last_greatest; int latest_greatest_diff = latest - greatest; NSLog(@"Mem: %10u (%10d) : %10d : greatest: %10u (%d)", info.resident_size, diff, latest_greatest_diff, greatest, greatest_diff ); } else { NSLog(@"Error with task_info(): %s", mach_error_string(kerr)); } last_resident_size = info.resident_size; last_greatest = greatest; }
杰森·cocoa的迅速解答:
func reportMemory() { let name = mach_task_self_ let flavor = task_flavor_t(TASK_BASIC_INFO) let basicInfo = task_basic_info() var size: mach_msg_type_number_t = mach_msg_type_number_t(sizeofValue(basicInfo)) let pointerOfBasicInfo = UnsafeMutablePointer<task_basic_info>.alloc(1) let kerr: kern_return_t = task_info(name, flavor, UnsafeMutablePointer(pointerOfBasicInfo), &size) let info = pointerOfBasicInfo.move() pointerOfBasicInfo.dealloc(1) if kerr == KERN_SUCCESS { print("Memory in use (in bytes): \(info.resident_size)") } else { print("error with task info(): \(mach_error_string(kerr))") } }
Swift 3.1 (截至2017年8月8日)
func getMemory() { var taskInfo = 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: &taskInfo) { $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 { let usedMegabytes = taskInfo.resident_size/1000000 print("used megabytes: \(usedMegabytes)") } else { print("Error with task_info(): " + (String(cString: mach_error_string(kerr), encoding: String.Encoding.ascii) ?? "unknown error")) } }
这是一个Swift 3版本:
func mach_task_self() -> task_t { return mach_task_self_ } func getMegabytesUsed() -> Float? { var info = mach_task_basic_info() var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout<integer_t>.size) let kerr = withUnsafeMutablePointer(to: &info) { infoPtr in return infoPtr.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { (machPtr: UnsafeMutablePointer<integer_t>) in return task_info( mach_task_self(), task_flavor_t(MACH_TASK_BASIC_INFO), machPtr, &count ) } } guard kerr == KERN_SUCCESS else { return nil } return Float(info.resident_size) / (1024 * 1024) }
以下是正确的答案:
“`
float GetTotalPhysicsMemory() { struct task_basic_info info; mach_msg_type_number_t size = sizeof(info); kern_return_t kr; kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size); if (kr == KERN_SUCCESS) return (float)(info.resident_size) / 1024.0 / 1024.0; else return 0; }
“`