10
votes

Est-ce que le dégagement d'objets / la répartition du tableau est vraiment nécessaire dans VB6 / VBA (avantages / contre?)

Beaucoup de ce que j'ai appris sur VB J'ai appris d'utiliser une analyse de code statique (en particulier l'analyseur de projet d'Aivosto). Et une une des choses qu'il vérifie est de savoir si vous avez nettoyé ou non tous les objets et les tableaux. J'avais l'habitude de le faire aveuglément parce que Pa dit de sorte. Mais maintenant que je connais un peu plus sur la façon dont VB publie des ressources, il me semble que ces choses devraient se passer automatiquement. S'agit-il d'une fonctionnalité héritée de Pre VB6 ou est-elle une raison pour laquelle vous devriez explicitement définir des objets sur rien et utiliser Effacer sur des tableaux?


0 commentaires

5 Réponses :


0
votes

Je le fais toujours pour de bonnes pratiques, vous ne savez jamais quelle exception pourrait faire si vous tombez dans un seul et vos objets ne sont pas distribués. Vous devez les libérer enfin des déclarations et vous assurer qu'ils n'utilisent aucune mémoire, sinon vous risquez de fonctionner dans une fuite de mémoire.

J'ai eu un problème à l'intérieur d'un système de traqueur de temps simple sur lequel le serveur a continué de creuser au hasard, il a fallu des semaines pour déterminer qu'il s'agissait d'une fuite de mémoire d'un objet censé s'autodétruire seul. Mon code a été jeté dans une exception et ne s'est jamais nettoyé après elle-même, ce qui lui entraîne le serveur (le site Web réel non du serveur) de descendre.


4 commentaires

Intéressant, peut demander quel type d'objet c'était? Quelle était la portée? Était-ce une exception trappable étant jetée, ou l'application a-t-elle vus juste de tomber? Lorsqu'une exception standard est lancée, la procédure est sortie. Même si, à l'exception, toutes les références locales sont toujours automatiquement détruites. Donc, s'il n'y avait pas de références à l'objet en dehors de la procédure, que faisait l'objet de rester "vivant"?


Il n'y a pas d'essai / prise / enfin de blocs ou d'exceptions dans VB6 / VBA.


Il n'y a pas d'essai / catch / enfin bloque, mais il y a des exceptions trappables. Jetez un coup d'œil à Err.rise.


Droite, je sais qu'il n'ya pas de VB6, mon point est qu'il peut y avoir quelque chose de similaire. Je n'ai pas fait VB6 dans un certain temps désolé :).



-2
votes

Oui, définissez tous les objets sur rien et nettoyer autant que vous le pouvez. VB6 est notoire pour avoir des fuites de mémoire lorsque vous ne nettoyez pas vos affaires. La collecte des ordures était sous-par VB6 / VBA.


5 commentaires

Salut Code Hard, j'ai souvent entendu ce sentiment exprimé. Ce que j'essaie, c'est un exemple concret / reproductible?


Il n'y a rien de mal avec le mécanisme de collecte des ordures de VB6. Ce sont d'autres composants qui ne relâchent pas correctement les références ou qui nécessitent une sémantique de déchirures très spécifique qui le brisent. Ce n'est pas la faute de Vb6 qu'il existe des composants mal écrits qui ne suivent pas les règles.


Parfois, vous devez expliquer explicitement des choses telles que des références d'objet circulaire également. Dans la portée générale, sortie libérera des rayons locaux et des réseaux de négociation, mais dans une portée de longue durée, tels que les données du module-global, vous serez peut-être bien conseillé de nettoyer tactiquement de manière tactique à l'occasion uniquement pour libérer des ressources de mémoire. Le point est là, n'est tout simplement pas une règle générale. Vous devez être conscient de ce que vous faites et quand il y a de la valeur dans une distribution précoce.


@Bob: bon point. Je pense que nous sommes d'accord: le point est effectivement qu'il n'y a tout simplement pas une règle dure et rapide pour libérer des objets. La mentalité "tout-must-be-be-So-So-So-So-So-So-So-Sound-Nature-ce qui" semble avoir été originaire d'une règle pouvant être toujours appliquée dans toutes les situations, et je ne peux pas dire que c'est "faux" de travailler Sous cette hypothèse, mais je pense qu'il est préférable de comprendre comment GC travaille dans VB6, vous pouvez donc prendre une décision éclairée. Ce qui me dérange, c'est que les gens obtiennent cette idée que la gestion de la mémoire de VB6 est horriblement brisée, mais c'est une conclusion incorrecte.


Merci Bob et Mike, bonne discussion. J'ai tendance à être d'accord avec Mike que vous ne devriez rien faire sans une bonne raison. Et je pense que Bob présente un scénario dans lequel vous pourriez avoir une bonne raison :) +1 2 Vous êtes tous les deux :)




4
votes

Le problème, si je comprends bien, cela a à voir avec le fait que VB6 (et ses prédécesseurs) a ses racines dans COM et son système de collecte de déchets comptant de référence.

Imaginez, par exemple, que vous déclarez une référence à un objet d'une bibliothèque tierce. Cet objet a un nombre de référence COM qui est utilisé à la fois pour le garder en vie et de déterminer quand il devrait être détruit. Il n'est pas détruit lorsque vous ne le réglez à rien, mais lorsque le nombre de références de l'objet atteint zéro.

Maintenant, tous les composants COM n'ont pas été écrits dans Visual Basic. Certains ont été écrits en C ou C ++. La manipulation des exceptions structurées n'existait pas toutes les langues. Donc, si une erreur est survenue, le nombre de références sur l'objet n'était pas garanti d'être correctement réduit et des objets COM étaient connus de suspendre plus longtemps que ce qu'ils étaient destinés à. Ce n'était pas un problème avec Visual Basic, en soi. C'était un problème com. (Et cela, vous pourriez noter, c'est pourquoi .NET n'utilise pas de comptage de référence.)

C'est pourquoi les développeurs de base visuels sont devenus obsédants quant à la libération des références d'objets avant de quitter des routines. Vous ne savez simplement pas ce qu'est un composant que vous allocant est de créer sous le capot. Mais lorsque vous relâchez votre référence, vous libérez au moins votre compte de référence. Il est devenu presque un mantra religieux. Déclarer, utiliser, libération. C'était la manière de faire les choses.

Bien sûr, Visual Basic pourrait être meilleur ou plus rapide dans les variables de la déséroférence que j'ai déclaré sur la pile. Mais Dammit, je veux qu'il soit évident que ces objets ont été libérés. Une petite assurance va un long chemin lorsque vous essayez de suivre une fuite de mémoire.


0 commentaires

2
votes

Avez-vous lu cette page Web Aivosto (des créateurs de Project Analyzer)?

Si vous utilisez des variables statiques, Il est important de récupérer la mémoire ils occupaient quand vous n'avez pas besoin de la variables plus. Avec dynamique la mémoire variables n'est pas tellement de problème, parce qu'ils sont détruits lorsque la procédure se termine.

En d'autres termes, vous n'avez pas besoin de vous soucier des variables locales ordinaires, non statiques et locales.


1 commentaires

+1 pour remarquer que :) Bien que ce soit un jour assez rare quand j'utilise la statique. J'utilise généralement simplement des variables de niveau de module privé si j'ai besoin de quelque chose de rappelé.