Garbage Collector dans Android

J’ai vu de nombreuses réponses Android suggérant d’appeler le garbage collector dans certaines situations.

Est-ce une bonne pratique de demander le ramasse-miettes sous Android avant de faire une opération gourmande en mémoire? Si non, devrais-je seulement l’appeler si je reçois une erreur OutOfMemory ?

Y a-t-il d’autres choses que je devrais utiliser avant de recourir au ramasse-miettes?

Pour les versions antérieures à 3.0 Honeycomb : Oui, appelez System.gc() .

J’ai essayé de créer des Bitmaps, mais j’obtiens toujours une “erreur de mémoire hors mémoire”. Mais quand j’ai appelé System.gc() premier, ça allait.

Lors de la création de bitmaps, Android échoue souvent avec des erreurs de mémoire insuffisante et ne tente pas de collecter les données en premier . Par conséquent, appelez System.gc() et vous disposez de suffisamment de mémoire pour créer des bitmaps.

Si vous créez des objects, je pense que System.gc sera appelé automatiquement si nécessaire, mais pas pour créer des bitmaps. Il échoue juste.

Je recommande donc d’appeler manuellement System.gc() avant de créer des bitmaps.

D’une manière générale, en présence d’un ramasse-miettes, il n’est jamais recommandé d’appeler manuellement le GC. Un GC est organisé autour d’algorithmes heuristiques qui fonctionnent mieux lorsqu’ils sont livrés à eux-mêmes. L’appel manuel du CPG diminue souvent les performances.

Parfois , dans certaines situations relativement rares, un GC peut se tromper et un appel manuel au GC peut alors améliorer les performances. En effet, il n’est pas vraiment possible d’implémenter un GC “parfait” qui gérera la mémoire de manière optimale dans tous les cas. De telles situations sont difficiles à prévoir et dépendent de nombreux détails de mise en œuvre subtils. La “bonne pratique” consiste à laisser le GC fonctionner seul; un appel manuel au GC est l’exception, qui ne devrait être envisagée qu’une fois qu’un problème de performance réel a été dûment constaté.

En dehors de la mémoire dans l’application Android est très commun si nous ne gérons pas correctement le bitmap, la solution au problème serait

 if(imageBitmap != null) { imageBitmap.recycle(); imageBitmap = null; } System.gc(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 3; imageBitmap = BitmapFactory.decodeFile(URI, options); Bitmap scaledBitmap = Bitmap.createScaledBitmap(imageBitmap, 200, 200, true); imageView.setImageBitmap(scaledBitmap); 

Dans le code ci-dessus J’ai juste essayé de recycler le bitmap qui vous permettra de libérer de l’espace mémoire utilisé, de sorte qu’il peut ne pas y avoir de mémoire. Je l’ai essayé pour moi.

Si le problème persiste, vous pouvez également append ces lignes

 BitmapFactory.Options options = new BitmapFactory.Options(); options.inTempStorage = new byte[16*1024]; options.inPurgeable = true; 

pour plus d’informations consultez ce lien

http://voices.yahoo.com/android-virtual-machine-vm-out-memory-error-7342266.html


REMARQUE: En raison de la “pause” momentanée provoquée par l’exécution de gc, il est déconseillé de le faire avant chaque allocation bitmap.

La conception optimale est:

  1. Libérez tous les bitmaps dont vous n’avez plus besoin , par le code if / recycle / null affiché. (Faites une méthode pour aider avec ça.)

  2. System.gc();

  3. Allouer les nouvelles bitmaps.

Si vous obtenez une erreur OutOfMemoryError, il est généralement trop tard pour appeler le garbage collector …

Voici une citation du développeur Android:

La plupart du temps, la récupération de la mémoire se produit à cause des tonnes de petits objects éphémères et de certains éboueurs, comme les éboueurs générationnels, qui peuvent optimiser la collecte de ces objects afin que l’application ne soit pas interrompue trop souvent. Le garbage collector Android n’est malheureusement pas en mesure d’effectuer de telles optimisations et la création d’objects de courte durée dans des chemins de code critiques de performance est donc très coûteuse pour votre application.

Donc, à ma connaissance, il n’y a aucun besoin urgent d’appeler le gc. Il est préférable de dépenser plus d’efforts pour éviter la création inutile d’objects (comme la création d’objects à l’intérieur de boucles)

Mon application gère beaucoup d’images et elle est morte avec une erreur OutOfMemoryError. Cela m’a aidé Dans le fichier Manifest.xml Ajouter

  

Il semble que System.gc() ne fonctionne pas sur Art Android 6.0.1 Nexus 5x, donc j’utilise Runtime.getRuntime().gc(); au lieu.

En règle générale, vous ne devriez pas appeler GC explicitement avec System.gc (). Il y a même la conférence IO ( http://www.youtube.com/watch?v=_CruQY55HOk ) où ils expliquent ce que les pauses du GC enregistrent et dans lequel ils déclarent également ne jamais appeler System.gc () parce que Dalvik sait mieux que vous quand le faire.

D’un autre côté, comme mentionné ci-dessus, les processus déjà en GC dans Android (comme tout le rest) sont parfois bogués. Cela signifie que les algorithmes de Dalvik GC ne sont pas à égalité avec les JVM Hotspot ou JRockit et peuvent parfois faire défaut. Une de ces occasions est lors de l’allocation d’objects bitmap. C’est une opération délicate car elle utilise de la mémoire Heap et Non-Heap, et une seule instance d’object bitmap sur un périphérique limité par la mémoire est suffisante pour vous donner une exception OutOfMemory. Par conséquent, de nombreux développeurs suggèrent de l’appeler après que vous n’ayez plus besoin de ce bitmap, ce qui est même considéré comme une bonne pratique par certaines personnes.

Une meilleure pratique consiste à utiliser .recycle () sur un bitmap, car c’est ce à quoi cette méthode est destinée, car elle marque la mémoire native du bitmap comme pouvant être supprimée. Gardez à l’esprit que cela dépend de la version, ce qui signifie qu’il sera généralement requirejs sur les anciennes versions d’Android (Pre 3.0, je pense) mais ne sera pas requirejs sur les versions ultérieures. En outre, cela ne nuira pas beaucoup à son utilisation sur les versions plus récentes d’Ether (ne faites simplement pas cela en boucle ou quelque chose comme ça). Le nouveau runtime ART a beaucoup changé ici, car ils ont introduit une “partition” Heap spéciale pour les gros objects, mais je pense que cela ne fera pas beaucoup de mal avec ART ether.

Aussi une note très importante à propos de System.gc (). Cette méthode n’est pas une commande à laquelle Dalvik (ou JVM) est obligé de répondre. Considérez cela plus comme dire à la machine virtuelle “Pourriez-vous s’il vous plaît faire la collecte des ordures si ce n’est pas un problème”.

Meilleur moyen d’éviter les MOO lors de la création de Bitmap,

http://developer.android.com/training/displaying-bitmaps/index.html

Il n’est pas nécessaire d’appeler le garbage collector après une OutOfMemoryError .

C’est Javadoc dit clairement:

Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

Ainsi, le ramasse-miettes a déjà essayé de libérer de la mémoire avant de générer l’erreur, mais sans succès.

Je dirais non, car le développeur docs sur l’utilisation de la RAM :


GC_EXPLICIT

Un GC explicite, comme lorsque vous appelez gc () (que vous devez éviter d’ appeler et faire confiance au GC pour s’exécuter si nécessaire).

J’ai mis en évidence la partie pertinente en gras.

Jetez un coup d’œil à la série YouTube, Android Performance Patterns – elle vous montrera des astuces pour gérer l’utilisation de la mémoire de votre application (par exemple, en utilisant les ArrayMap et SparseArray s d’ SparseArray au lieu des HashMap s).

Note rapide pour les développeurs Xamarin .

Si vous souhaitez appeler System.gc() dans les applications Xamarin.Android, vous devez appeler Java.Lang.JavaSystem.Gc()