Erreur de mémoire insuffisante dans android en raison de l'augmentation de la taille du tas
J'obtiens des erreurs de Mémoire insuffisante. Je suis en train de travailler sur une application de chat en direct. Il fonctionne très bien mais quand je suis en cours d'exécution de l'application 1 à 2 heures sur le périphérique de la taille de segment de mémoire est en augmentation et quand elle a atteint à 16 MO de démarrage de l'application de l'accrochage et d'être écrasé après un certain temps et montrant out of memory due to heap size
parce que la résultante de la taille de segment de mémoire est plus que d'être allouées.
Je suis en train de tester mon application sur HTC Explorer. Dans mon application, la plupart des activités sont l'aide thread d'arrière-plan et pour cela, je suis en utilisant Asnyc Tâche.
J'obtiens le message d'erreur semblable à la suivante.
04-30 16:53:14.658: E/AndroidRuntime(5707): FATAL EXCEPTION: MagentoBackground
04-30 16:53:14.658: E/AndroidRuntime(5707): java.lang.OutOfMemoryError: (Heap Size=20167KB, Allocated=16063KB, Bitmap Size=355KB)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.util.ByteArrayBuffer.<init>(ByteArrayBuffer.java:53)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.io.AbstractSessionInputBuffer.init(AbstractSessionInputBuffer.java:82)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.io.SocketInputBuffer.<init>(SocketInputBuffer.java:98)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:173)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
04-30 16:53:14.658: E/AndroidRuntime(5707): at com.live2support.CustomHttpClient.executeHttpPost1(CustomHttpClient.java:163)
Est là la limite de taille de segment de mémoire? comment puis-je résoudre mon problème?
source d'informationauteur nikki
Vous devez vous connecter pour publier un commentaire.
Votre question comporte deux parties:
1) Comment puis-je déterminer la taille du segment de mémoire sur mon appareil de test?
2) Pourquoi mon application de dépasser la taille de mon tas?
Concernant la question 1, vous pouvez déterminer la taille du segment de mémoire sur votre appareil de test directement dans votre code en appelant:
De l'exécution.getRuntime().maxMemory();
Voir ce post pour plus d'informations sur cette méthode, ainsi que quelques exemples de tailles de tas disponible sur plusieurs appareils.
Aussi, si vous exécutez un dispositif enracinée, il y a peut être un moyen de régler directement (et vérifier) la taille du segment de mémoire via l'interface. Par exemple, dans CyanogenMod différentes versions d'Android, à partir du menu Paramètres, vous pouvez sélectionner "CyanogenMod paramètres", puis "Performance", et puis "VM taille de segment de mémoire", et visualiser directement (et de modifier) la taille du segment de mémoire pour votre appareil. Soyez prudent, car le réglage de la taille de segment de mémoire trop faible peut rendre votre appareil se comporte mal ou pour le pire.
Au sujet de la question 2: Vous n'avez pas fourni suffisamment d'informations pour diagnostiquer votre problème spécifique, et dans tous les cas, faire un diagnostic de seconde main est difficile au mieux. Votre meilleur pari pour la résolution de ce problème (et pour l'apprentissage de quelque chose de valeur durable dans le processus) serait de devenir familier avec certains de la très puissante mémoire outils d'analyse disponibles dans Android (dont certains sont également intégrées dans l'environnement de développement Eclipse). J'utilise ces outils à partir d'Eclipse, c'est ce que je vais décrire ci-dessous.
Tout d'abord, assurez-vous que votre Eclipse version est à jour en installant la dernière version d'Eclipse (par exemple, l'Indigo).
Prochain, dans Eclipse, cliquez sur Aide/Installer un Nouveau Logiciel, puis cliquez sur la liste déroulante en haut et sélectionnez
Ensuite, ouvrez l'Objectif Général catégorie Outils en cliquant sur le signe plus à côté d'elle, et sélectionnez la Mémoire de l'Analyseur et aussi la Mémoire de l'Analyseur (Graphiques) [facultatif]. L'installation de ces outils.
Ensuite, sélectionnez Fenêtre/Préférences, puis Android/DDMS, et sélectionnez le HPROF action "Ouvrir dans Eclipse." Ce sera la cause de tout HPROF heap dump fichier que vous générez à partir de DDMS à être le format approprié pour Eclipse, et également provoquer d'être automatiquement ouvert dans l'Éclipse de la Mémoire de l'Analyseur (qui vient d'être installé au-dessus).
Maintenant, ouvrez DDMS en sélectionnant Fenêtre/Ouvrir la Perspective/Autre/DDMS. Sélectionnez l'icône Périphériques (qui ressemble à un téléphone) sur la gauche et faites glisser la fenêtre de sorte qu'il est ancré quelque part vous pouvez le voir facilement.
Assurez-vous que votre appareil est connecté au PC via USB, et que votre application est en cours d'exécution.
Dans l'onglet Périphériques que vous avez créé, sélectionnez votre application en cours d'exécution du processus. Exécutez l'application, au point où il a occupé assez de mémoire que vous savez qu'il a fui, mais pas tant que ça plante. Maintenant, cliquez sur le Dump HPROF icône du Fichier dans l'onglet périphériques. Après un bref délai, il vous sera proposé un choix de rapports sur votre tas. Essayez la Fuite des Suspects Rapport pour obtenir commencé. Ce rapport va s'ouvrir dans la Mémoire Outil d'Analyse. Il vous indique où votre application est l'utilisation de la mémoire. Vérifier les différents types d'objets et de voir si elles ont l'aspect gonflé par rapport à la quantité de données que vous pouvez vous attendre à; si oui, cela peut indiquer une fuite.
Ici est un bon tutoriel décrivant plus en détail la façon de générer et d'explorer des tas à l'aide de DDMS et la Mémoire de l'Analyseur de l'Outil.
De retour dans DDMS (ou la perspective DDMS dans Eclipse), vous pouvez sélectionner l'onglet Allocation Tracker lorsque votre appareil est connecté, puis votre appareil à partir de l'onglet périphériques, puis sélectionnez votre application de processus à partir de la liste pour ce périphérique. Puis, dans l'onglet Allocation Tracker, cliquez sur le Démarrer bouton Tracking, puis exécutez votre application pertinente des opérations (ceux que vous suspectez une fuite), puis cliquez sur Obtenir les Allocations bouton, puis sélectionnez Arrêter le Suivi de bouton.
Afin d'afficher toutes les allocations qui ont eu lieu pendant que vous étiez suivi (il y a des limites à la quantité qu'elle va stocker). En cliquant sur l'un de ces va vous emmener à la pile au moment de l'attribution, et en cliquant sur n'importe quelle partie de vidage de pile va vous prendre pour le code source qui a été impliqué dans la répartition.
Ces outils devrait vous donner un aperçu de ce qui pourrait être la cause de votre application à une fuite de mémoire.
Il ressemble à un classique de la fuite de mémoire. Vous dites, que vous utilisez
AsyncTask
pour la connexion. Il est très facile de fuite de contexte avec une AsyncTask sur les modifications de la configuration (par exemple, la rotation de l'appareil) lorsque vous ne savez pas comment l'utiliser correctement.Première chose - je vous recommande fortement de regarder ce: http://www.youtube.com/watch?v=_CruQY55HOk
Pour vérifier si vous en avez une fuite de mémoire, de faire pivoter votre appareil et de vérifier comment le Garbage Collector se comporte. Vous devriez avoir quelque chose comme
GC_... freed 211K, 71% free 300K/1024K, external 0K/0K, paused 1ms+1ms
dans votre LogCat presque à chaque fois que vous tournez. Surveillez les changements dans cette partie:300K/1024K
. Si vous n'avez pas de fuites de mémoire, la première partie doit croître et devenir plus petit après quelques GCs. Si vous avez une fuite de mémoire, il va croître et se développer, au point de OOM erreur.Si vous assurez-vous que vous avez une fuite de mémoire de cette façon, ce que vous devez faire est d'installer un TAPIS pour Eclipse, apprendre à l'utiliser (dans le cas du film) et de trouver ce qu'elle provoque.
Mon pari serait une mauvaise mise en œuvre de AsyncTask - ne vous détacher détruit l'Activité et de l'attacher à la nouvelle? Si pas, commencer à le faire (il y a un excellent exemple par CommonsWare) ou de passer à
AsyncTaskLoader
qui le fait pour vous et qui est généralement un grand remplacement pourAsyncTask
(pas seulement pour le chargement des trucs).Juste ajouter
android:largeHeap="true"
dans la balise application au sein de votre manifeste.Votre tas de limite de taille est dépendant du périphérique. Sur un 2.x l'appareil, je m'attends à environ 20 ou 32 MO est votre limite. Voir Android taille de segment de mémoire sur les différents téléphones/appareils et versions de système d'exploitation pour plus d'informations sur les tailles de tas.
De votre trace de la pile, il ressemble à
com.live2support.CustomHttpClient.executeHttpPost1()
est au centre de votre problème.Cela peut être fait de deux manières, selon votre système d'exploitation Android.
android:largeHeap="true"
dans la balise application de Android manifeste pour demander une plus grande taille de segment de mémoire, mais cela ne fonctionnera pas sur tous les pré Nid d'appareils.Avant de HeapSize assurez-vous que vous avez entré la bonne taille, qui ne va pas affecter d'autres applications ou systèmes d'exploitation de la fonctionnalité. Avant de paramètres il suffit de vérifier la taille de votre application prend & puis définissez la taille juste pour réaliser votre travail. Ne pas utiliser beaucoup de mémoire sinon, d'autres applications peuvent affecter.
Référence: http://dwij.co.in/increase-heap-size-of-android-application