Java a sa propre implémentation de collecte des ordures afin qu'elle ne nécessite aucun destructeur comme C ++. Cela rend le développeur Java paresseux dans la mise en œuvre de la gestion de la mémoire. p>
Nous pouvons toujours avoir destructeurs avec un collecteur de déchets où le développeur peut libérer des ressources et qui peut sauver le travail du collectionneur de déchets. strong> Cela pourrait améliorer la performance de l'application. Pourquoi Java ne fournit-il aucun mécanisme de destructeur? p>
développeur strong> n'a pas de contrôle sur GC mais il / elle peut contrôler ou créer un objet fort>. Puis
10 Réponses :
Vous affirmez que "la collection de la poubelle est très coûteuse" - pourriez-vous revenir sur des preuves? La collection de déchets n'est certainement pas GRATUIT EM> mais les collectionneurs à ordures modernes sont très bons. Notez que l'une des façons dont le GC est capable d'être efficace est qu'il sait em> C'est la seule chose à faire une allocation de mémoire et de la classique (pour des objets gérés). Autoriser un développeur explicitement em> un objet pourrait entraver cette efficacité. Vous auriez également besoin de vous inquiéter de ce qui se produirait si un développeur essayait de "utiliser" un objet libéré: p> proposez-vous que chaque objet devrait avoir un drapeau supplémentaire pour "Cela a-t-il été explicitement libéré" qui doit être vérifié sur chaque déréférence? Cela ressemble à une recette pour la catastrophe, d'être honnête. P> Vous avez raison, cela permet aux développeurs Java d'être paresseux dans cette zone em>. C'est une bonne chose. Les IDES permettent aux développeurs d'être paresseux aussi - comme les langages de haut niveau, etc. La patainess autour de la mémoire L'allocation permet aux développeurs dans des environnements gérés de dépenser leur énergie à se préoccuper des problèmes d'entreprise plutôt que de la gestion de la mémoire. P> P>
Je pense que les développeurs sont paresseux (dans un bon sens) par la nature!
Gratuit code> n'est pas GRATUIT i> non plus.
@ Tomhawtin-tackline comme un gars dit, si quelque chose est libre, cela signifie que vous êtes le produit :)
@Jamesb "Je choisis une personne paresseuse à faire un travail difficile. Parce qu'une personne paresseuse trouvera un moyen facile de le faire." - Billus Gatus.
Vous avez fait un bon cas que permet aux développeurs de Java i> est paresseux dans cette zone, afin qu'ils puissent passer leur temps sur d'autres choses. Mais vous n'avez pas répondu à la partie pourquoi il est interdit i> de détruire volontairement un objet quand recherché.
Vous avez ceci -1 parce que les développeurs sont des développeurs et non des gestionnaires. Si vous dites que leur travail est "inquiétant des problèmes d'affaires", uniquement parce que leur travail est une programmation dans un environnement de la société, vous manipulez la signification des mots.
@Peterhorvath: Je dis que leur travail est "inquiétant des problèmes d'affaires" dans lesquels les développeurs sont payés pour atteindre un objectif réel - et si l'utilisation de la collection de déchets leur permet d'atteindre cet objectif du monde réel plus rapidement que la gestion manuelle de la mémoire ( Et je crois que ça fait), alors c'est une bonne chose. Je ne pense pas que cela manipule le sens des mots du tout. Je pense toujours aux "exigences commerciales" du code même s'il est open source, par exemple.
Vous avez la capacité de contrôler la destruction des objets en Java. Il utilise simplement un idiome différent:
Connection conn = null; try { conn = ... // do stuff } finally { try { conn.close(); } catch (Exception e) { } }
Cela ne détruit pas l'objet i> - il libère des ressources associées à l'objet (la poignée du système d'exploitation sous-jacente, vraisemblablement) mais pas l'objet lui-même.
Si vous savez que vous n'avez plus de gros objets, il vous suffit de les références à NULL. Cela pourrait peut-être accélérer la collecte des ordures de ces objets. p>
Très rarement une bonne idée, imo. Dans la plupart des cas, le collecteur des ordures est suffisamment intelligent pour vous de travailler pour vous, et il clutter votre code. Il y a quelques exceptions près, mais ils ne sont pas très courants dans mon expérience.
C'est vrai. Dans la plupart des temps, vous n'en avez pas besoin de cela, mais c'est une possibilité pour le programmeur qui pense qu'il pourrait tromper quelque chose de Java pour faire quelque chose comme libérer une mémoire.
C'est au moins une indication de ce que vous voulez, même si Java l'ignore ou l'a optimisé. Et cela fera plus de bugs de mise en œuvre lancer une exception, ce qui est une bonne chose. Une vitesse de gc est possible, en fonction de l'algorithme, les utilisations de la mise en œuvre VM, mais cela ne devrait pas être une raison de le faire.
Le destructeur C ++ n'est pas un moyen de détruire des objets - c'est un ensemble de fonctionnement à effectuer lorsque l'objet est déstolité. En Java, vous n'avez aucun contrôle sur le temps où les objets sont destructés (ils peuvent être même jamais détruits), ce qui permet d'exécuter un code important à exécuter à la destruction de l'objet est fortement découragé (bien que possible - finaliser la méthode code>) . Si vous ne demandez pas à un destructeur, mais pour un moyen de détruire explicitement un objet donné, vous invitez des références en suspens dans votre code. Ils ne sont pas les bienvenus. P>
C ++ ne vous donne pas de contrôle "Pas de contrôle sur le moment où des objets sont destructs". C ++ utilise une finalisation déterministe. Lorsque vous supprimez un objet, son destructeur est immédiatement appelé, puis son stockage est immédiatement distribué. Il n'y a pas de C ++ gc. Je ne dis pas que c'est nécessairement une bonne chose, mais c'est comment fonctionne C ++.
@andyjohnson: Soit vous avez mal compris que ma grammaire était cassée. Quoi qu'il en soit j'ai essayé de le réparer. Pas de contrôle sur le temps où les objets sont destructés est en Java. En C ++, vous avez le contrôle total (règles compliquées de modulo sur la durée de vie des temporaires).
@andyjohnson: Le stockage est immédiatement indisponible i>. La réelle DealLocation i> peut arriver ultérieurement - le traitement par lots n'est pas inoubliable.
@andy Assurez-vous qu'il y a un collecteur de déchets pour C ++, il n'est tout simplement pas standard: HPL.HP .com / personnel / hans_boehm / gc
La collection de déchets est très chère. P> blockQuote>
En fait, pour des applications complexes, la performance de la collection de déchets est compétitive avec em> gestion de stockage manuelle basée sur
malloc code> /
libre code>. Il y a un papier classique par Benjamin Zorn qui clairement démontre ceci. Dans cet article, Zorn décrit comment il a modifié de nombreux applications intensives en tas à utiliser un collecteur de déchets conservateurs au lieu de
Malloc code> et
gratuit code>. Puis il a comparé les versions originales et modifiées des applications. Le résultat était une performance comparable. P>
Ce document a été publié dans la pratique et l'expérience des logiciels en 1993. Si vous ne l'avez pas lu, vous n'êtes pas qualifié de prononciples sur l'inefficacité de la collection de déchets. P>
Notez que cette recherche a été réalisée avec un collecteur de déchets em> conservateur de 1993 - Vintage. Un collecteur conservateur est un balayage de marque sans aucune compactage; I.E. Les objets non-ordures ne bougent pas. Ce dernier signifie que l'attribution de l'espace pour les nouveaux objets est aussi lente et compliquée que
malloc code>. En revanche, les collectionneurs à ordures modernes (par exemple Java 6/7) sont des collecteurs de copie générationnels qui sont beaucoup plus efficaces. Et puisque la copie compacte les objets non-ordures restants, l'allocation est beaucoup plus rapide. Cela rend le GC encore plus compétitif ... Si on pouvait trouver un moyen de faire la comparaison. Sup> p>
Développeur n'a pas de contrôle sur GC mais il / elle peut contrôler ou créer un objet. Alors pourquoi ne pas leur donner la capacité de détruire les objets? P> blockQuote>
Cela dépend de ce que vous entendez précisément par "destruct". P>
en Java, vous avez la possibilité d'assigner
null code>. Dans certaines circonstances, cela peut hâter la destruction d'un objet. P> li>
en Java, vous pouvez utiliser les finaliseurs et
référence code> pour noter qu'un objet est sur le point d'être détruit ... et donc quelque chose à ce sujet. P> li>
en Java, vous pouvez définir une méthode
ferme () code> (ou équivalent) sur n'importe quel objet et faire quelque chose de nécessaire. Puis appelez-le explicitement. P> li>
en Java 7, vous avez la construction "Essayer avec les ressources" pour appeler automatiquement
ferme () code> sur les ressources sur la sortie de la portée. P> LI> ul>
Cependant, vous ne pouvez pas faire supprimer un objet Java maintenant. La raison pour laquelle cela n'est pas autorisé est qu'il permettrait à un programme de créer des références pendantes, ce qui pourrait entraîner une corruption du tas et des accidents de la JVM aléatoires. p>
Ce n'est pas la voie Java. La philosophie est que l'écriture de programmes fiables est plus importante que l'efficacité. Bien que certains aspects de Java ne suivent pas cela (par exemple le filetage) Personne ne veut la possibilité d'accidents JVM aléatoires. P>
@Abhishek: Si vous étiez Attendant une réponse i> une réponse qui conteste votre affirmation, pourquoi l'avez-vous incluse comme une affirmation de commencer? Pourquoi pas seulement demander "la collecte des ordures est chère?" Cela viendrait comme moins argumentative, imo.
En fait, je ne suis pas juste i> contestant l'affirmation. Je fournis également une référence à des preuves difficiles que (IMO) ne prévient i>.
Pour le Downvoter anonyme aléatoire: n'hésitez pas à expliquer pourquoi vous pensez que c'est une mauvaise réponse.
Cela fait du développeur Java paresseux dans Mise en œuvre de la gestion de la mémoire. P> blockQuote>
Non, il les libère pour effectuer travail utile. em> p>
et la collecte des ordures est très cher. p> blockQuote>
comparé à quoi? Faits? Les figures? Vous avez environ 20 ans de retard avec cette remarque. La prise en charge de Java seule déprime efficacement cette affirmation. P>
Cela pourrait améliorer les performances de l'application. P> blockQuote>
ou non. Avez-vous eu des faits pour susciter? P>
Alors pourquoi ne pas leur donner la capacité de détruire les objets? p> blockQuote>
Parce que ce n'est pas nécessaire? p>
"Ce n'est pas nécessaire" bien, comment pouvez-vous avoir votre code de nettoyage? Java ne garantit rien sur finaliser (). Vous pouvez avoir toute l'initialisation dans le constructeur que vous voulez, mais pour le nettoyage Activités I>, Java n'offre rien.
@foo au contraire. Java propose le bloc enfin {}.
Si vous insistez dans la verbosité: Java ne fait aucune garantie sur la méthode Finaliser () et il n'a rien à offrir en ce qui concerne la destruction fiable de l'objet. (Oui, au niveau du bloc de contrôle, il existe enfin le bloc - qui est à peu près inutile pour l'objet LiveCycle.)
@FOO La réponse à votre premier commentaire est que vous pouvez faire appel à un code de nettoyage dans un bloc enfin {}, et c'est ce que Java propose en ce qui concerne la «destruction de l'objet fiable». Vous ne pouvez pas continuer à prétendre que cela n'existe pas.
Je ne prétends pas que cela n'existe pas, j'ai explicitement reconnu cela exister. Mais vous devez l'écrire à nouveau et encore, pour chaque bloc, au lieu de la mettre en œuvre une fois pour la classe. Pour une langue qui prétend être OO, il s'agit d'une solution de contournement au mieux.
@foo suspect la majorité des programmeurs Java n'a pas rencontré une situation où il est utile d'avoir un destructeur. Mon préféré personnel est dans la journalisation / la traçage où vous écrivez un code comme celui-ci: {fn_enter ( fonction b>); faire quelque chose(); } La macro FN_Enter crée un nouvel objet qui provoque l'enregistrement / connecté de la fonction> ". Lorsque cet objet sort hors de portée, les destructeurs provoquent "le nom" de la fonction "" pour être enregistré / tracé. Cela vous permet d'avoir à appeler explicitement fn_exit à la sortie, et cela empêche les journaux incompatibles car même si vous revenez tôt, le destructeur est appelé = gagner.
@FOO En l'absence de toute définition acceptée de ce qui constitue une langue «OO», ou tout accord quant à quelles langues sont vraiment «OO», le cas échéant, ou toute preuve que Java »prétend être OO 'dans le sens de votre intention de , quoi que ce soit, votre dernière remarque ne veut rien dire quoi que ce soit. Votre raisonnement sur le point sur la circulaire.
@EJP: Java étant OO - voici la source: oracle.com/technetwork/ java / intro-141325.html à quelle définition de OO qui peut faire référence à, nous pourrions creuser dans l'histoire de Java (pitié qu'ils perdaient les pré-postconditions, BTW). - Bien que je ne vois pas tout à fait là où se passe cet argument, je refuse les "verges sur la circulaire": Java manque de destruction / désert des éléments de contrôle pour les classes. Pouvons-nous d'accord sur cela au moins?
@foo bien sûr, mais cela n'a rien à voir avec Java étant une langue oo. Il manifeste l'encapsulation, l'héritage et le polymorphisme: c'est suffisant, par la seule définition formelle dont je suis au courant (Wegner 1987).
Le destructeur C ++ n'est pas un moyen de détruire des objets - il s'agit d'un ensemble d'opérations à effectuer lorsque l'objet est détruit. P> blockQuote>
Je pense que vous êtes déroutant la terminologie. Voici comment je le vois: p>
créer strud> objet = d'abord allouer la mémoire, puis construire fort> via constructeur p>
détruire strud> objet = premier destruct fort> via destructeurs, puis transmettez la mémoire p> Comment la mémoire est allouée et traitée dépend. Si vous utilisez
Nouveau code> et
Supprimer code>, la gestion de la mémoire est effectuée par
VOID * Opérateur Nouveau (Taille_T) CODE> et
Opérateur vide Suppr (VOID *) code>. p>
Destructeurs sont appelés lorsque l'objet
Vous ne pouvez pas faire i> l'utilisateur appelle une méthode Destroy (). Si vous avez besoin de contrôle pour libérer correctement les ressources internes associées à l'objet, vous en avez besoin de la méthode (comme un destructeur) qui est implicitement appelé.
@jarmod Si l'utilisateur n'appelle pas détruire (), il fuit une ressource. Je voulais dire quelque chose comme Idisose code> dans .net. Vous appelez
Dispose () code> pour jeter expliquer un objet.
Un destructeur C ++ est utile pour libérer les ressources toutes les ressources em> appartenant à l'objet, pas seulement la mémoire. Il peut s'agir de fichiers, de sockets, de mutiles, de sémaphores ou de toute autre ressource. L'utilisation d'un destructeur est une manière intelligente de prévenir les fuites de ressources. Enveloppez la manipulation des ressources dans une classe C ++ et faire un destructeur qui libère toutes les ressources allouées. Je ne vois aucune méthode de cette telle en Java. Vous devez explicitement libérer la ressource, ce qui peut être délicat s'il y a de nombreux chemins de sortie possibles. P>
Non, Java ne supporte pas les destructeurs. Tout libérant la tâche de mémoire est effectué par le collecteur des ordures. P>
Java a sa propre fonctionnalité de gestion de la mémoire utilisant un collecteur de déchets. Lorsque vous utilisez finaliser () l'objet devient disponible pour la collecte des ordures et vous n'avez pas besoin d'appeler explicitement le destructeur. C # et Java ne veulent pas que vous vous inquiétions de destructeurs, car ils ont une caractéristique de la collecte des ordures. P>
Java est une langue bytecode, elle a une très forte détection des ordures. Si vous pouviez permettre aux gens de définir leurs propres destructeurs, il est probable qu'ils puissent faire des erreurs. En automatisant le processus, Java a l'intention d'empêcher ces erreurs. P>
Votre question a aussi la réponse. Au lieu de destructeur, le Java effectue les collections de la poubelle
-1 Pour des revendications non fondées sur la collecte des ordures.
@stevendick ici, j'essaie de comprendre que la différence entre GC et destructeur.
@Abhishek: Si c'est votre seul objectif, vous devriez éviter de donner de telles revendications controversées et non fondées.
"Cela rend le développeur Java paresseux dans la mise en œuvre de la gestion de la mémoire" Il s'agit d'une ordures complètes. Vous pouvez être aussi paresseux en C ++ lorsque vous ne comprenez pas ce que vous faites. Les développeurs compétents de Java sont capables de gérer la mémoire (en prévenant des fuites) aussi bien, cela n'est tout simplement pas explicitement.
Il existe un moyen beaucoup plus simple de réduire les frais généraux de l'allocation d'objet / destruction. Créez moins d'objets. Java est optimisé pour gérer très efficacement les objets temporaires vécus de courte durée, pour des objets plus longs que suggéré par Apporach ne ferait pas beaucoup de différence.
Ce n'est pas moins que Java est plus facile de se développer et a plus de temps à pied sur le marché ne signifie pas que les développeurs Java sont paresseux, tout simplement plus productifs. ;)
-1 question biaisée. C'est une honte, c'était une doublée pour être une question intéressante avant de découvrir que j'étais paresseux
Les votes négatifs de votre question, avec un gros votes positifs de réponse gagné un badge d'or pour @jon Skeet!
@Om: Upvote davantage, donc les autres partagent la renommée
Voir aussi Stackoverflow.com/questions/171952/ ...