2009-04-24 5 views
88

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/Leaks. Cela ne m'intéresse pas, 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.Récupérer par programme l'utilisation de la mémoire sur l'iPhone

Merci.

+0

Man, je récupère déjà l'utilisation de la mémoire avec succès; Mais pouvez-vous aider à répondre à mes questions connexes? https://stackoverflow.com/questions/47071265/how-to-analyze-stack-info-of-a-thread – Paradise

Répondre

129

Pour obtenir les octets réels de la mémoire 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 meilleure idée 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 la structure info.virtual_size qui vous donnera le nombre d'octets disponibles mémoire virtuelle (ou la mémoire allouée à votre application en tant que mémoire virtuelle potentiel en tout état de cause). Le code auquel pgb se connecte vous donnera la quantité de mémoire disponible pour l'appareil et quel type de mémoire il est.

+4

merci, exactement ce que je cherchais. Cette méthode de magasin d'applications est-elle sûre? – Buju

+0

@Jason Coco - comment appeler ci-dessus la méthode ?? –

+0

@NiteshMeshram Définissez simplement la fonction comme indiqué, link in, et appelez la fonction comme 'report_memory();'. –

19

Voici report_memory() amélioré pour afficher rapidement l'état des fuites dans 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

taille doit être TASK_BASIC_INFO_COUNT au lieu de sizeof (info) - cette erreur copier-coller à de nombreux endroits avec le même code – Speakus

25

Les en-têtes pour TASK_BASIC_INFO disent:

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

Voici une version à l'aide 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

Vous avez une idée pourquoi la valeur enregistrée ici est environ deux fois plus grande sur un simulateur que les rapports Xcode et trois fois sur un vrai appareil? –

+1

Je ne sais pas pourquoi la différence. Cela ferait une bonne nouvelle question. – combinatorial

+1

J'ai trouvé la différence. C'est en raison de la mémoire résidente pas les octets en direct –

8

solution rapide de la réponse de Jason 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))") 
    } 
} 
+0

Que faire si l'on veut savoir quelle RAM utilise une autre application (skype)? –

2

est ici une Swift 3 Version:

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(En date du 8 Août, 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

est inférieure à la réponse correcte:

`` `

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

`` `

Questions connexes