6
votes

Combien d'appels de fonction causeront un débordement de pile

Bonjour les développeurs Android / Java,

Lorsqu'une fonction appelle une fonction et cette fonction appelle un autre, etc. Existe-t-il une règle générale?

La raison pour laquelle je demande est parce que je suis maintenant ce qui est plus efficace (conception sage) pour mes 5 cartes de joueurs jeu

Solution 1: < / p> xxx

solution 2: xxx

i préférez la solution 2 donc s'il y a un crash, je peux voir tous les appels de la fonction de p1 à i = 0 jusqu'à p4 à i = 100

mais avec la solution 1, la pile est beaucoup plus courte mais quand il y a un crash, je verrai au début des boucles a la fonction appelée de la fonction () Où l'accident est arrivé

Que suggérez-vous? Je sais que c'est un peu 2 questions dans 1 mais elles sont très liées

merci tous


1 commentaires

Pourquoi vous n'appelez pas la fonction la plus imbriquée à la première fois.


6 Réponses :


1
votes

Je ne pense pas que vous puissiez dire qu'un numéro général d'appels de fonction X déclenchera un débordement de la mémoire de pile. Cela dépend des fonctions, de leurs arguments, de leurs types de retour, etc., tous sont conservés sur la mémoire de la pile, de sorte que différentes fonctions peuvent prendre différentes quantités de mémoire (pile).

En tout cas, vous ne devez jamais compter sur le code qui obtient même à distance à distance de pleurer la pile en essayant de prendre en compte la quantité de pile utilisée. Votre code doit toujours être très dégagé de déborder la pile.


2 commentaires

Croyez-le ou non, je n'avais jamais pensé à empiler débordement dans ma vie de programmation car je ne me suis jamais proches de celui-ci (était toujours un appel spécifique à faire une action). Mais comme je suis en train de développer des cartes, j'ai remarqué que les joueurs ont pour se déclencher dans cette question. Vous suggérez donc que je doive toujours essayer de garder l'appel de la fonction imbriquée au minimum? 100 appel imbriqué dans une pile est trop Eh!


Eh bien, oui, bien que les 100 appels imbriqués honnêtement ne sont pas si nombreux. Peut-être que le périphérique Android étant limité a une JVM (ou tout ce qu'ils ont) qui alloue moins de mémoire de pile par rapport à un PC de bureau. En tout cas, la documentation Android spécifie la conservation des appels de méthode au minimum si la performance est un gros problème (ce qui est en quelque sorte le cas ici). Donc, oui, essayez de le faire pour que moins la méthode et la pile soient placées dans la mémoire (pile).



2
votes

Il n'y a pas de règle générale pour les fonctions récursives ou imbriquées créant un débordement de pile. Au lieu de cela, elle dépend de la mémoire disponible sur la pile, qui peut varier en fonction des allocations de systèmes matériels et d'exploitation sous-jacents.

Il est difficile de déterminer quelle méthode d'appels de fonction est meilleure pour votre situation sans voir plus de code. Je voudrais parvenir à l'ancienne option (première) car il est un peu plus explicite envers ce qui se passe et évite de relier des méthodes possibles et des instances d'objet pouvant ne pas être nécessairement dépendantes les unes des autres. Si vous êtes principalement préoccupé par les rapports d'erreur, vous pouvez essayer d'ajouter des journaux dans votre code pour permettre plus de connaissances verbeuses de ce qui se passe, ainsi que de regarder la décharge de la trace de la pile. Espérons que ce lien peut aussi vous aider également: http://developer.android.com/tools/ Débogage / index.html


1 commentaires

Merci pour la réponse la plus précise.Si je ne suis plus meilleure réponse, je vais l'accepter :)



2
votes

Je pense que Shivan Dragon a raison, il n'y a pas de quantité correcte d'appels, cela provoquera un débordement. Cependant, vous pouvez le tester avec une fonction récursive vraiment simple: xxx

et l'appelez comme: xxx

puis voir jusqu'où il va .


1 commentaires

Correct, mais je veux être si proche que chaque appareil est différent. Mais vaut la peine d'essayer



0
votes

cadre En Java a: la table de la table et des opérandes de variables locales. Cette taille de la pile est constante et chaque méthode pourrait avoir une taille différente de celle-ci. En raison de la spécification JVM, la taille de la pile d'opérande est stockée dans l'attribut méthodes code in max_stack champ: xxx

Cette taille est calculée pendant la compilation et Pourraient être modifiés par JVM lorsque vous appuyez sur StackoverflowException . Spécification JVM:

Les conditions exceptionnelles suivantes sont associées à des piles de machine virtuelle Java: si le calcul dans un thread nécessite une pile de machine virtuelle Java plus grande que celle autorisée, la machine virtuelle Java jette un stackoverflowerror. Si les piles de machine virtuelles Java peuvent être étendues de manière dynamique et une expansion est tentée mais une mémoire insuffisante peut être mise à la disposition de l'extension ou si une mémoire insuffisante peut être mise à la disposition de la pile de machine virtuelle Java initiale pour un nouveau fil, le Java Virtual la machine jette un ex-memororyError.

Pour résumer: Cela dépend de la quantité de mémoire que votre JVM est autorisée à obtenir. Sur différentes postes de travail / smartphones, vous pourriez avoir différentes valeurs de mémoire disponible. C'est pourquoi vous ne devriez pas écrire de code qui dépend de telles choses. Si vous pensez que OutofMemoryException pourrait se produire, essayez de résoudre votre problème itératif au lieu de récursif.


0 commentaires

3
votes

Dans mon expérience, un débordement de pile en Java est presque toujours dû à une erreur de programmation. Voir Types typiques ici .

Maintenant, votre deuxième solution est, imo, assez laide ... presque une erreur de programmation. En supposant que N = 100 est (sorte de) la durée de votre jeu, il semble tort que la consommation de mémoire (taille de la pile) augmente avec elle. Je n'aime pas du tout cette solution.

Quand il y a un crash, je verrai au début des boucles un appelé fonction de fonction () où l'accident est arrivé

Je ne vois pas l'avantage réel. Pourquoi ne pas mettre un essayer de prendre un bloc de sorte que, dans le cas d'un crash, vous pouvez imprimer le numéro d'itération?


1 commentaires

Ok c'est une sorte de réponse que je cherchais. Je pense que je voudrais aller avec le premier



0
votes

Ceci est descendu au principe de la récursion vs itération.

Récursion vous permet d'écrire un algorithme de manière simple; plus facile à comprendre et plus rapide à mettre en œuvre. Des algorithmes récursifs peuvent être convertis en algorithmes itératifs qui seront plus efficaces de mémoire et plus efficaces du processeur.

La décision est donc l'une des performances VS Simplicity / Coding Effort.

Voici un fil de ce sujet: Récursion ou itération?


0 commentaires