2009-04-24 4 views
88

Я пытаюсь получить объем памяти, которую использует мое приложение для iPhone в любое время, программно. Да, я знаю об ObjectAlloc/Leaks. Меня это не интересуют, только чтобы узнать, можно ли написать код и получить количество используемых байтов и сообщить об этом через NSLog.Программно извлекать использование памяти на iPhone

Спасибо.

+0

Человек, я уже успешно использую память; Но можете ли вы ответить на мои вопросы? https://stackoverflow.com/questions/47071265/how-to-analyze-stack-info-of-a-thread – Paradise

ответ

129

Чтобы получить фактические байты памяти, используемые вашим приложением, вы можете сделать что-то вроде приведенного ниже примера. Тем не менее, вам действительно нужно ознакомиться с различными инструментами профилирования, а также спроектировать их, чтобы дать вам гораздо лучшую картину общего использования.

#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, даст вам объем памяти, доступный устройству, и какой тип памяти он имеет.

+4

спасибо, именно то, что я искал. Безопасен ли этот магазин приложений? – Buju

+0

@ Джейсон Коко - как позвонить выше метод ?? –

+0

@NiteshMeshram Просто определите функцию, как показано, включите и вызовите функцию, например 'report_memory();'. –

19

Это свойство 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; 
} 
+1

размер должен быть TASK_BASIC_INFO_COUNT вместо sizeof (info) - эта ошибка копируется во многие места с одинаковым кодом – Speakus

25

Коллекторы для 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)); 
    } 
} 
+0

Любая идея, почему значение, зарегистрированное здесь, примерно в два раза больше на симуляторе, чем отчеты Xcode, и три раза на реальном устройстве? –

+1

Я не знаю, почему разница. Это создаст новый новый вопрос. – combinatorial

+1

Я нашел разницу. Это из-за резидентной памяти, а не живых байтов –

8

Swift решение ответ Jason Coco «s:

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))") 
    } 
} 
+0

Что делать, если мы хотим знать, сколько бара использует какой-либо другой applicaiton (skype)? –

2

Вот 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) 
} 
3

Swift 3,1(По состоянию на 8 августа 2017)

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")) 
    } 

} 
0

Ниже правильный ответ:

`` `

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; 
} 

`` `

Смежные вопросы