Comment augmenter la taille du tas d'une application Android?

125

J'écris une application Android qui utilise plusieurs modèles 3D. Un tel modèle avec des textures peut prendre beaucoup de mémoire. J'ai découvert que le fabricant fixe une limite à la taille du tas qu'une application peut utiliser. Par exemple, ma tablette Samsung Galaxy Tab 8.9 P7310 peut occuper 64 Mo de mémoire.

Existe-t-il un moyen d'augmenter cette taille de mémoire qu'une application peut utiliser?

cooxie
la source

Réponses:

210

Vous pouvez utiliser android: largeHeap = "true" pour demander une taille de tas plus grande, mais cela ne fonctionnera pas sur les périphériques pré-Honeycomb. Sur les appareils antérieurs à 2.3, vous pouvez utiliser la classe VMRuntime, mais cela ne fonctionnera pas sur Gingerbread et au-dessus.

La seule façon d'avoir une limite aussi grande que possible est d'effectuer des tâches gourmandes en mémoire via le NDK, car le NDK n'impose pas de limites de mémoire comme le SDK.

Vous pouvez également charger uniquement la partie du modèle actuellement affichée et charger le reste selon vos besoins, tout en supprimant les parties inutilisées de la mémoire. Cependant, cela peut ne pas être possible, selon votre application.

Raghav Sood
la source
NDK a l'air intéressant. Puis-je l'utiliser en combinaison avec mon code déjà écrit avec le SDK?
cooxie
3
Cela dépend complètement du code que vous avez. Je ne suis pas un expert du NDK et je ne connais que les bases. Je vous recommande de poser cette question avec une description de votre code sur le groupe Google android-ndk, ou de publier une nouvelle question sur SO spécifique à cela avec la balise android-ndk.
Raghav Sood
Je me demande si nous ne pouvons pas "simplement" utiliser Unity3D comme réponse plus spécifique à la question ("utilise plusieurs modèles 3D") ... Impossible de trouver rapidement des preuves claires sur l'utilisation de NDK par unité.
cregox
3
largeHeap=trueFTW
Luis Artola
2
les développeurs d'API Android sont vraiment drôles, ils sont comme si vous vouliez plus de tas? Ok, demandez-le, ce n'est que pour ceux qui en ont besoin ... en attendant, chaque développeur l'ajoute comme première chose à ajouter lorsque l'application entrera en production :)
AndroidLover
110

Existe-t-il un moyen d'augmenter cette taille de mémoire qu'une application peut utiliser?

Les applications exécutées au niveau d'API 11+ peuvent avoir android:largeHeap="true"sur l' <application>élément dans le manifeste pour demander une taille de tas plus grande que la normale, et getLargeMemoryClass()sur ActivityManagervous dira quelle est la taille de ce tas. Toutefois:

  1. Cela ne fonctionne que sur l'API niveau 11+ (c.-à-d. Honeycomb et au-delà)

  2. Il n'y a aucune garantie de la taille du gros tas

  3. L'utilisateur percevra votre demande de gros tas, car cela forcera ses autres applications à sortir de la RAM et mettra fin aux processus d'autres applications pour libérer de la RAM système pour une utilisation par votre grand tas

  4. En raison du n ° 3, et du fait que je pense que android:largeHeapcela sera abusé, le support pour cela peut être abandonné à l'avenir, ou l'utilisateur peut être averti à ce sujet au moment de l'installation (par exemple, vous devrez demander une autorisation spéciale pour cela )

  5. Actuellement, cette fonctionnalité est peu documentée

CommonsWare
la source
@CommonsWare si avoir un largeHeap n'est pas disponible, comment puis-je supprimer des objets précédemment chargés (comme des images)?
Jeongbebs
@MiguelRivera: Pour les images, idéalement vous recyclez leur mémoire (voir inBitmapsur BitmapOptions). Au - delà, supprimer toutes les références à eux, et finalement ils se ramasse-miettes.
CommonsWare
et quelle décision suggérez-vous?
Gennadiy Ryabkin
@zest: Je ne sais pas de quoi vous parlez, désolé.
CommonsWare
2
@Eftekhari: Pas directement, pour votre application. Avoir plus de choses peut vous amener à passer plus de temps CPU à les parcourir, mais les détails dépendraient de ce que vous faites avec la mémoire et ne sont pas directement liés à la demande android:largeHeap. Cependant, la demande d'un tas volumineux peut nuire à l'expérience de l'utilisateur dans son ensemble, en forçant d'autres processus d'application à se terminer plus tôt que ce qui aurait été nécessaire autrement.
CommonsWare
22

vous ne pouvez pas augmenter dynamiquement la taille du tas.

vous pouvez demander à en utiliser davantage en utilisant android:largeHeap="true"dans le manifeste.

vous pouvez également utiliser native memory (NDK & JNI), de sorte que vous contourniez la limitation de la taille du tas.

voici quelques articles que j'ai publiés à ce sujet:

et voici une bibliothèque que j'ai créée pour cela:

développeur android
la source
@ par application, le tas limite-t-il au niveau Java et natif est-il différent? ie exemple sur s5 devcie 128 Mo java heap limite et natif peut prendre un autre 128 mb?
NitZRobotKoder du
La taille du tas est constante pour chaque application (la taille dépend du matériel et de la ROM) et devrait être la même pour tous. La mémoire native est la vraie mémoire de l'appareil, mais elle est bien sûr également limitée, car une partie est utilisée par le système d'exploitation.
développeur android
Je voulais dire si mon application utilise, disons natif .so + plateforme android java + logique java POJO + JavaScript. Android a-t-il une taille de tas différente à chaque niveau?
NitZRobotKoder
@NitZRobotKoder Non. La taille du tas est pour le monde Java / Kotlin, où vous pouvez obtenir une exception OOM si vous en utilisez trop. Pour le reste, c'est la mémoire native.
développeur android
6

Utilisez le deuxième processus. Déclarer comme AndroidManifestneuf Serviceavec

android:process=":second"

Échange entre le premier et le deuxième processus sur BroadcastReceiver

Yura Shinkarev
la source
5

Cela peut être fait de deux manières en fonction de votre système d'exploitation Android.

  1. Vous pouvez utiliser la android:largeHeap="true"balise d'application du manifeste Android pour demander une taille de tas plus grande, mais cela ne fonctionnera pas sur les appareils antérieurs à Honeycomb.
  2. Sur les appareils antérieurs à la version 2.3, vous pouvez utiliser la classe VMRuntime , mais cela ne fonctionnera pas sur Gingerbread et au-dessus Voir ci-dessous comment le faire.
VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE);

Avant de définir HeapSize, assurez-vous que vous avez entré la taille appropriée qui n'affectera pas les autres applications ou fonctionnalités du système d'exploitation. Avant les paramètres, vérifiez simplement la taille de votre application, puis définissez la taille juste pour accomplir votre travail. N'utilisez pas autant de mémoire, sinon d'autres applications pourraient affecter.

Référence: http://dwij.co.in/increase-heap-size-of-android-application

Développeur Web à Pune
la source
4
Donc apparemment, <2.3 a un moyen, et> 2.3 a un moyen, mais 2.3 est foutu!
Michael
3

D'après ce dont je me souviens, vous pouviez utiliser la VMRuntimeclasse dans les premières versions d'Android, mais maintenant vous ne pouvez plus.

Je ne pense pas que laisser le développeur choisir la taille du tas dans un environnement mobile puisse être considéré comme si sûr. Je pense qu'il est plus facile de trouver un moyen de modifier la taille du tas dans un périphérique spécifique (pas du côté de la programmation) qu'en essayant de le modifier à partir de l'application elle-même.

Jack
la source
0

L'augmentation de Java Heap mange injustement les ressources mobiles déficitaires. Parfois, il suffit d' attendre le ramasse-miettes , puis de reprendre vos opérations après la réduction de l'espace du tas. Utilisez alors cette méthode statique .

Zon
la source