Récupérer par programme l'utilisation de la mémoire sur iPhone

J'essaie de récupérer la quantité de mémoire que mon application iPhone utilise à tout moment, par programmation. Oui, je suis au courant de ObjectAlloc / fuites. Je ne suis pas intéressé par ceux-ci, seulement pour savoir s'il est possible d'écrire du code et d'obtenir la quantité d'octets utilisés et de le signaler via NSLog.

Merci.

91
demandé sur Coocoo4Cocoa 2009-04-24 23:08:54

7 réponses

Pour obtenir les octets de mémoire réels que votre application utilise, Vous pouvez faire quelque chose comme l'exemple ci-dessous. Cependant, vous devriez vraiment vous familiariser avec les différents outils de profilage, car ils sont conçus pour vous donner une bien meilleure image de l'utilisation globale.

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

Il y a aussi un champ dans les informations de structure.virtual_size qui vous donnera le nombre d'octets de mémoire virtuelle disponible (ou de mémoire allouée à votre application en tant que mémoire virtuelle potentielle dans tout événement). Le code auquel pgb LIE vous donnera la quantité de mémoire disponible pour l'appareil et le type de mémoire qu'il est.

133
répondu Jason Coco 2017-04-09 17:49:39

Les en-têtes deTASK_BASIC_INFO dire:

/* Don't use this, use MACH_TASK_BASIC_INFO instead */

Voici une version utilisant 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));
    }
}
28
répondu combinatorial 2014-12-05 19:21:40

Voici report_memory() amélioré pour afficher rapidement l'état de fuite dans le 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;
}
19
répondu Doug Null 2011-07-09 15:20:29

Solution rapide de la réponse deJason Coco :

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))")
    }
}
8
répondu Nazariy Vlizlo 2017-05-23 12:02:42

Swift 3.1 (en août 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"))
    }

}
4
répondu BennyTheNerd 2017-08-09 18:48:58

Voici une version 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
répondu jeffbailey 2016-10-21 13:15:21

Voici la bonne réponse:

```

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

```

0
répondu rensq 2017-11-03 07:38:09