2013-04-16 3 views
0

Cela se produit sur un système embarqué qui utilise une version personnalisée de la plate-forme Android 4.0.2. Je vois une de nos applications d'activité Android atteindre environ 400 Mo (taille rss lorsque "ps" est invoqué) et se faire tuer par le tueur Linux OOM. La plate-forme Android a été configurée avec une taille de segment maximale définie sur 62M. Je ne sais pas comment Dalvik VM a laissé l'activité passer à 400MB.Processus de mémoire insuffisante Linux tuant mon application Android

L'application ne devrait-elle pas avoir des exceptions Java hors mémoire lorsque le tas atteint environ 60 Mo? Nous ne voyons pas ces exceptions Java dans les journaux logcat ou dans les traces anr.

Nous avons implémenté un exemple d'activité qui alloue des tableaux d'octets en séquence et définit chaque octet sur une valeur fictive. Nous voyons des exceptions Outofmemory lorsque l'activité a alloué environ 60 Mo.

Y a-t-il des chemins d'allocation dans android qui ne sont pas comptabilisés dans le budget de tas? L'activité affiche les png bitmap téléchargés à partir d'un site Web.

Voici les résultats de "getprop" sur notre plateforme.

$ adb shell getprop | grep -i tas

J'apprécie tous les pointeurs.

Merci

: Edité Note: ci-dessous est sortie ps. Le Pss et Us sont autour de 316M qui est bien au-dessus.

 
          PID  Vss  Rss  Pss Uss cmdline 
logcat: hd[0]: pexecd(65): 982 351512K 351316K 326300K 316632K mytest.home^M 
logcat: hd[0]: pexecd(65): 660 679916K 61044K 57200K 56952K ./videngine^M 

RAM: 741764K total, 20320K free, 2148K buffers, 80104K cached, 24964K shmem, 10368K slab 

Répondre

2

Les allocations directes dans le code natif ne comptent pas contre ce tas de Java totale. Il peut y avoir d'autres possibilités (peut-être des pages cartographiées et peuplées à partir de fichiers?).

Si vous avez un build android personnalisé, vous pouvez définir des valeurs de tueur OOM pour préserver votre propre application.

+0

Il s'agit d'une application Android sans aucun JNI personnalisé en cours. Je veux que JVM jette des exceptions de MOO au lieu de laisser le processus atteindre 400 Mo. – videoguy

+0

Il ne peut pas être personnalisé (en fait j'avais pensé - peut-être à tort - ce n'était même pas votre application), mais que fait-il? Il y a beaucoup de JNI dans le code de la plateforme. –

+0

Cette application charge une page Web en utilisant le contrôle du navigateur Web Android. On dirait que le moteur Webkit fait beaucoup d'allocations en code natif en dehors du tas Java Android basé sur la page en cours de téléchargement. Cela explique pourquoi l'application est passée à 300 Mo +. – videoguy

2

Je vois une de nos applications d'activité Android de plus en plus à environ 400 Mo (taille rss lorsque "ps" est invoquée)

Pour citer Dianne Hackborn, en ce qui concerne la sortie de ps sur Android: « Vss et les colonnes Rss sont fondamentalement bruit (ce sont l'espace d'adressage direct et l'utilisation RAM d'un processus, où si vous additionnez l'utilisation de la RAM à travers les processus, vous obtenez un nombre ridiculement grand) "

Je vous encourage vivement à lisez her epic SO answer on measuring an app's memory footprint. Notamment, Rss ne joue aucun rôle dans son analyse, au-delà de la citation que j'ai citée plus haut. Par conséquent, je suggère de ne pas s'inquiéter de Rss et se concentrer sur d'autres mesures.

+0

Je vais jeter un coup d'oeil au fil. Merci d'avoir partagé. C'est ce que je vois quand "ps" est invoqué. logcat: hd [0]: pexecd (65): 982 351512K 351316K 326300K 316632K mytest.home^M logcat: hd [0]: pexecd (65): 660 679916K 61044K 57200K 56952K ./native_engine^M ... – videoguy

1

Voici ce que vous pouvez faire pour avoir une idée de la mémoire utilisée par votre application.

Aller à DDMS, et créer un vidage de tas en cliquant sur l'icône qui ressemble à ceci: HPROF

Suivant convertir le HPROF en format Android au format régulier de HPROF en utilisant l'outil hprof-conv dans le androir-sdk/tools dossier.

Ensuite, ouvrez le vidage de tas avec Eclipse Memory Analyser (MAT), et regardez l'arbre dominateur, vous verrez une liste de variables que votre application force le collecteur de déchets Dalvik (GC) à conserver. Faites un clic droit sur eux et allez à "Path the GC root", et "Exclure les références faibles", vous montrera les références qui gardent ces objets en vie. Regardez et voyez si vous avez des références expirées qui ont été conservées comme une fuite de mémoire.

Vous pouvez regarder this video pour beaucoup de façon détaillée de trouver une fuite de mémoire dans l'application Android.

+0

Merci pour l'info et le lien. Nous allons réparer la fuite de mémoire. Ce qui me dérange, c'est pourquoi le runtime de Dalvik n'a lancé aucune exception OutOfMemory. – videoguy

+1

Tout n'est pas alloué sur le tas de Dalvik, diverses choses vont grossir, et elles peuvent refléter dans la mémoire de l'application (par exemple l'onglet de l'application en cours d'exécution), comme JIT ou autre chose. Je recommande vraiment de regarder la vidéo à partir d'E/S, il explique en détail ce qui se passe sur le tas, et comment un exp OutOfMem est lancé. – wangyif2