web-dev-qa-db-fra.com

Est-il nécessaire de définir les objets sur Nothing dans les fonctions VBA

Je lis toujours qu'il est recommandé de ne rien définir lorsque les objets sont terminés. Mais je ne les utilise normalement que dans des fonctions à l'intérieur de formes.

La référence n'est-elle pas perdue et la mémoire libérée lorsque la portée de la fonction est laissée, que les objets aient été définis sur Nothing? 

c'est-à-dire qu'il est vraiment nécessaire de faire:

Set db = Nothing
Set record_set = Nothing
56
Ramon

VB utilise un ramasse-miettes appelé "comptage de références".

Fondamentalement, lorsqu'une variable sort de la portée, le compteur de référence sur l'objet référencé est décrémenté. Lorsque vous affectez la référence à une autre variable, le compteur de références est incrémenté.

Lorsque le compteur atteint zéro, l'objet est prêt pour la récupération de place. Les ressources d'objet seront libérées dès que cela se produira. Une variable locale de fonction référencera probablement un objet dont le nombre de références ne dépassera jamais 1, ainsi les ressources de l'objet seront libérées à la fin de la fonction.

Définir une variable sur Nothing permet de réduire explicitement le compteur de référence.

Par exemple, vous lisez dans un fichier et définissez la variable d'objet de fichier sur Nothing juste après l'appel ReadAll(). Le descripteur de fichier sera publié immédiatement, vous pouvez prendre votre temps pour traiter son contenu. 

Si vous ne définissez pas sur Nothing, le descripteur de fichier sera peut-être ouvert plus longtemps que nécessaire.

Si vous n'êtes pas dans une situation du type "il faut débloquer des ressources précieuses", laisser les variables sortir du champ d'application est acceptable.

71
Tomalak

La collecte des ordures est rarement parfaite. Même dans .NET, il est parfois fortement conseillé d’inviter le système à effectuer la récupération de place rapidement.

Pour cette raison, j’ai explicitement cloturé close et réglé sur Nothing recordsets lorsque j’en ai terminé.

14
BIBD

La toute dernière ligne de la rubrique d'aide relative à " Recordset.Close " dans l'aide de Microsoft DAO et la référence du développeur Access est la suivante:

"Une alternative à la méthode Close est De définir la valeur d'une variable d'objet .__ sur Nothing (Set dbsTemp = Nothing)."

http://msdn.Microsoft.com/en-us/library/bb243098.aspx

Dans cet esprit, cet article de la base de connaissances Microsoft intitulé "Comment prévenir le fardeau de la base de données après l'utilisation de DAO (Data Access Objects)", vous indique que vous devez fermer explicitement si vous ne souhaitez pas gonfler. Vous remarquerez que l'article est un peu vague sur les détails; la section "Cause" n'est pas claire, presque au point d'être du charabia. 

http://support.Microsoft.com/kb/289562

Symptômes: Une base de données Microsoft Access a commencé à gonfler (ou à croître rapidement en taille ) après avoir implémenté l'accès aux données Objets (DAO) pour ouvrir un jeu d’enregistrements. 

CAUSE: Si vous ne relâchez pas un la mémoire de recordset chaque fois que vous parcourez le code du jeu d’enregistrements, DAO peut recompiler, en utilisant plus de mémoire et augmenter la taille de la base de données. 

Plus d'informations: lorsque vous créez un Recordset (ou un objet QueryDef) dans code, ferme explicitement l'objet quand vous avez fini Microsoft Access ferme automatiquement Recordset et Objets QueryDef dans la plupart des cas conditions. Cependant, si vous Fermez explicitement l'objet dans votre code, vous pouvez éviter occasionnellement cas où l'objet reste ouvrir.

Enfin, permettez-moi d'ajouter que je travaille avec les bases de données Access depuis 15 ans et que je laisse presque toujours mes variables d'enregistrements déclarées localement sortir de la portée sans utiliser explicitement la méthode Close. Je n'ai pas fait de test, mais cela ne semble pas avoir d'importance.

12
Shane Miskin

Lorsque vous utilisez ASP classic (script côté serveur), il est important de ne définir aucun objet à la fin, car ils ne sont pas hors de portée tant que le serveur [virtuel] n'est pas arrêté. .

Pour cette raison, tous les exemples de script MS VB montraient toujours que les objets étaient fermés et réglés sur rien. Pour que les extraits de script puissent être utilisés dans des environnements tels que ASP classic où les objets ne sortent pas de la portée.

Il existe rarement des situations dans lesquelles vous souhaitez coder des processus de longue durée dans lesquels les objets ne sont pas hors de portée et où vous vous retrouvez à court de mémoire physique si vous ne libérez pas explicitement les objets.

Si vous vous trouvez en train de coder ASP classic ou si vous exécutez des processus dans une étendue globale pour une autre raison, alors oui, vous devriez explicitement libérer les objets.

2
david

Les références sont supposées être nettoyées lorsque la variable sort de la portée. Cela s’est sans doute amélioré avec les versions ultérieures du logiciel, mais il n’était pas fiable à un moment donné. Je crois qu'il reste une bonne pratique de définir explicitement les variables sur "Rien".

2
John Mo

Je mets généralement toujours cela à la fin de mes procédures, ou appelle un sous-marin "CloseRecordSet" avec si je l'utilise au niveau du module:

Private Sub Rawr()
On Error GoTo ErrorHandler

    'Procedural Code Here.

    ExitPoint:
        'Closes and Destroys RecordSet Objects.
        If Not Recset Is Nothing Then
            If Recset.State = 1 Then
                Recset.Close
                Conn.Close
            End If
            Set Recset = Nothing
            Set Conn = Nothing
        End If
        Exit Sub

    ErrorHandler:
        'Error Handling / Reporting Here.
        Resume ExitPoint
End Sub

De cette manière, la procédure se termine (que ce soit normalement ou à cause d’une erreur), les objets sont nettoyés et les ressources libérées.

Le faire de cette façon est tout à fait sûr dans le sens où vous pouvez simplement le glisser dedans et il ne fera que ce qui est nécessaire en ce qui concerne la fermeture ou la destruction de l'objet recordset/connection, si celui-ci a déjà été fermé (en raison d'une erreur d'exécution ou fermez-le tôt comme vous le devriez, cela vous assure).

Ce n’est vraiment pas très compliqué et il est toujours préférable de nettoyer vos objets lorsque vous en avez terminé avec eux pour libérer des ressources immédiatement, quel que soit le déroulement du programme.

1
BobT