Je gère une application J2ME et je rencontre des problèmes de mémoire grave. merci, EDIT: strong>
J'ai donc construit à une autre étape pour effacer la chaîne d'entrée énorme et traiter ses données et l'effacer.
Mais cela n'a pas résolu le problème jusqu'à ce que je fixe INPUT = NULL CODE> STROND> ET PAS
INPUT = "" STROND>. < p> ne devrait-il pas être la même chose en termes de gestion de la mémoire? Quelqu'un peut-il m'expliquer la différence s'il vous plaît? P>
Rayt p>
Je veux toujours signaler une réponse comme solution. Je pense que les remarques mmyers vont dans la bonne direction. P> p>
6 Réponses :
Vous pouvez consulter Cet article de L'annulation explicite est simplement la
pratique de définir des objets de référence
à NULL quand vous avez fini avec
eux. et en outre, p>
Dans la colonne de septembre 1997 "Java Developer Connect Tech Tips" (voir Ressources), Soleil a averti de ce risque et a expliqué comment l'annulation explicite était nécessaire dans des cas comme l'exemple POP () ci-dessus. Malheureusement, les programmeurs prennent souvent ce conseil trop loin, en utilisant explicitement nulling dans l'espoir d'aider le collectionneur des ordures. Mais dans la plupart des cas, il n'aide pas le collecteur à ordures du tout em>, et dans certains cas, il peut en réalité blesser em> la performance de votre programme. strong> p>
blockQuote> entrée = null code> supprime (le collecteur de déchets supprime) l'objet en mémoire, tandis que
entrée = "" code> instancie une chaîne code> objet code> La chaîne vide
"" code>. En définissant l'entrée sur NULL, vous effectuez une entrée
code> un objet vide, de sorte qu'il ne prendra pas aucune mémoire em>, tout en réglant entré = "", vous le réglez sur un nouvel objet, qui va certainement prendre certains em> la mémoire (évidemment, il devrait être minimal). P>
IBM CODE> Parlez de Java GC et de la performance, qui décourage ma recommandation précédente. Il dit: p>
Mais de toute façon, l'ancienne chaîne n'a pas de références, elle devrait donc être éligible à la collecte.
L'une quelconque change quelle entrée se réfère donc à ce qu'il aura le même effet du point de vue des collectionneurs à déchets.
Vous avez raison, le contenu original de l'entrée doit être supprimé dès que LISTXML et l'entrée ne vous y référent plus. Mais en définissant une entrée à NULL, vous sont i> raconter le GC le supprimer dès que possible.
Il n'y a rien de spécial à définir une variable de référence à NULL par rapport à une autre valeur. Ce n'est certainement pas un signal magique à GC pour "Supprimer le plus tôt possible".
@Voyager Où dit-il que la définition d'une variable pour NULL indique à la GC de "supprimer ceci dès que possible?" Je ne pense pas que ce soit vrai.
@ Kevin, Pavel: Je me suis trompé par un mauvais conseil que j'ai appris à l'université, que je suis heureux d'avoir corrigé.
L'utilisation d'une stringbuffer pourrait être une meilleure approche p>
Une partie de celle-ci a déjà été répondue ici à SO: P>
Builder String et Stringbuffer à Java P>
Pourquoi utiliser Stringbuffer dans Java au lieu de l'opérateur de concerts de chaîne p>
C'est en fait une solution bien meilleure.
Chaque fois que vous écrivez entrée + = bla () code> Un nouvel objet de chaîne est créé, tout le contenu de l'ancien obtenu est copié dans celui avec la sortie de
bla () code> annexé, et l'ancienne entrée code> code> est marquée pour GC. C'est très lent et inefficace.
Stringbuffer Code> la résout.
L'efficacité n'est pas sa question ici. Il a une question sur la mise en œuvre sous-jacente de NULL par rapport à une chaîne vide. Donc, vous n'avez pas répondu à sa question. S'il avait posé des questions sur la performance, alors il serait bon de lui dire de profiler le code des goulots d'étranglement. Avait-il trouvé un problème causé par une concaténation de cordes copieuses, puis conseiller l'utilisation Stringbuffer serait une bonne réponse à cette question. Mais pourquoi lui dire comment optimiser quand vous ne savez pas qu'il a un problème de performance et ne lui demandait même pas?
Chaque variable est en fait un pointeur sur "Data" en mémoire. P>
Entrée = "" attribue l'entrée à un objet de chaîne. Il a une longueur (0) et un tableau vide, ainsi que quelques autres pièces de données associées à celle-ci. P>
entrée.length () retournera 0 à ce stade. P>
entrée = null rend le point d'entrée sur "invalide". NULL est une sorte de cas particulier qui signifie que ce pointeur pointe de rien, il n'est pas affecté. p>
entrée.length () va maintenant lancer une exception parce que vous appelez .Longueur sur rien. P>
donc 'null' peut consommer un peu moins de mémoire que "" mais les deux devraient être meilleurs que de grandes chaînes
Oui, mais je reçois un sentiment vraiment génial chaque fois que quiconque "vide" une variable. Celui de l'exemple doit être une variable de méthode et devrait donc disparaître la seconde la méthode. La définir à NULL ou "" "probablement simplement, car il est plus pour l'exécution d'optimiser. En d'autres termes, si l'entrée = NULL fait quelque chose de plus, cela signifie que l'entrée n'est pas suffisamment portée. Fixez-le en premier!
dans les chaînes Java sont des objets et des noms de variables d'objet sont toujours des pointeurs. Si vous avez une chaîne appelée entrée et tapez entrées = null, cela pointe une entrée dans un espace null en mémoire. Si vous avez entré = "", il crée une chaîne qui ne contient aucun texte, une chaîne vide. P>
Je voudrais ajouter un peu à la réponse de Voyager: P>
L'énoncé Si l'entrée == "", alors "si (entrée.isempty ()) L'énoncé J'espère que cela aide et à toute personne d'autre, n'hésitez pas à corriger les erreurs même si elles sont subtiles. P>
-bn p> entrée = ""; code> à partir d'un point de vue de la collection de déchets est identique à l'écriture
entrée = "abcde ..."; code>, en ce que ni la déclaration ne nulifie la Instance d'objet
entrée code>, mais les deux modifient simplement le contenu de la chaîne d'entrée code> code> variable. Aussi, pour la précision et la clarification,
entré = quelque chose " code> modifie le contenu de
entrée code>, tandis que
String entrée =" "; code> instanciates
INPUT code>. p>
serait vrai, mais code> si (entrée == null)` serait faux. P>
Concernant la collecte des ordures h2>
entrée = null; code> décrémente le nombre de références sur cet instance d'objet spécifique, qui, s'il s'agit de la dernière référence à code> entrée code>, alors
entrée < / Code> sera marqué pour la collecte des ordures qui se passera non-déterminatinalement alias quand le collecteur des ordures qui lui rend. Un cas où
entrée = null; code> ne serait pas réellement signalé
entrée code> pour la collection de déchets serait: si
entrée code> a également été transmis à une collection; Jusqu'à ce que
entrée code> a été supprimé de la collection, il conserverait le nombre de références de décrémenter et donc d'être des déchets collectés. P>
entrée = "" code> est pas i> "modifie le contenu de la chaîne d'entrée code> code> variable"; Cela ne le réaffecte que la décrémentation du nombre de références sur la chaîne d'origine. Du point de vue de la chaîne d'origine originale, toute réaffectation i> de
entrée code> décrémente le nombre de références et ne fait aucune différence pour savoir si la réaffectation est de
" " code>,
null code> ou
" jon skeet " code>.
Je vois, vous dites que entrée = ""; code> ne signifie pas que l'ancienne valeur de
entrée code> doit être marquée dans la phase "Mark" avant de pouvoir être collecté dans la phase "Balayer", tandis que
entrée = null; code> le fait marquer, de sorte que vous n'avez besoin que d'attendre une phase "marque"?
@myers J'avais l'impression que Java's GC n'a pas conservé les comptes de référence, car avec GC générationnelle, cela prendrait plus de mémoire qu'il ne vaut la peine.
Il est important de se rappeler que les variables sont des références aux objets, pas d'objets eux-mêmes. Les objets de chaîne Java sont immuables - inchangables. Vous ne pouvez modifier que quelles références variables, pas l'objet de chaîne lui-même. @Imageist Oui, Java ne conserve pas les comptes de référence, il figure en fait si un objet est référencé par une variable en suivant le graphique de référence au moment de l'exécution.
Cela ne conserve pas les comptes de référence en soi i>, mais toute référence forte empêchera la GC de récupérer un objet.
MMYers, pourriez-vous s'il vous plaît élaborer le 24 juillet 19:34? Spécifiquement je suis curieux de la déclaration "en soi"; J'aimerais mieux comprendre le GC mieux (parlant de quoi, avez-vous une recommandation ou une source préférée d'aller sur le fonctionnement interne de la JVM, du GC, etc.)
Plutôt que de spéculer sur la raison pour laquelle le collecteur des ordures ne collecterait pas votre objet, je préfère rassembler des preuves sur la situation. D'autres ont déjà posté leurs suppositions. P>
Si possible, créez des fichiers de décharge de tas pour observer la mémoire dans votre JVM lorsqu'il exécute votre code, puis inspectez-les pour voir quels objets y existe. p>
Voici une page Web qui vous dit comment faire cela: http://twit88.com/blog/2008/12 / 19 / Java-Dépannage-Memory-Problème / P>
bonne chance! p>
Une autre idée: écrivez un programme court qui ne fait rien de plus que de créer de gros objets de chaîne, puis d'allumer le mode de collecte des ordures verbeux, pour voir ce qui se passe là-bas. Si vous pouvez reproduire le comportement dans un petit programme, vous pouvez l'étudier plus facilement. Je pense que vous pouvez constater que la JVM sur un PC peut se comporter différemment de la JVM dans un appareil J2ME comme un téléphone portable. P>
La raison pour laquelle je ne peux pas répondre à cette question est, je ne m'attendrais pas à ce que Java se comporte de cette façon. Il ne devrait faire aucune différence entre S = NULL ou S = "". Rayt a déclaré qu'il faisait une différence, il doit donc y avoir une lacune dans ma compréhension. J'apprends mieux en lisant des informations provenant de sources autoritaires (Sun et IBM sont bonnes) et d'expérimentation directe.
Je suppose que cela dépend de la fonctionnement du collecteur de poubelles J2ME, mais de la réaffectation
entrée code> à n'importe quoi (
null code>,
"" code> "" code> i Comme une pizza " code>) devrait permettre à GC récupérer la chaîne d'entrée énorme.
Voir aussi Stackoverflow.com/Questtions/473685/...
Désolé, je ne connais pas la réponse. Je sais juste une mauvaise réponse quand je le vois.