Jag har hört dubbla budskap på om man skall eller inte skall sätta sina objektvariabler till Nothing när man är klar med dem. Vad gäller för VB6 egentligen? Jag hade för mig att man alltid skulle göra det i VB6, men att i .NET så sköter Garbage Collection det automatiskt. Hej, Ett exempel när det blir en viss skillnad ifall man tar bort referensen eller inte, är om man skapar objekt av samma typ efter varandra:Hur är det egentligen med Set object = Nothing i VB6?
Ser man i hjälpen (MSDN) för VB6 så står det att man kan eller bör men det står ingenting om man måste eller vad som annars händer.
Om man måste göra det i VB6 och man inte gör det- blir det minnesspill då, eller vad?
Själv har jag alltid tagit för vana att sätta alla mina objektvariabler till Nothing så fort jag är klar med dem, men nu blev jag osäker när jag har hört så många olika besked.......Sv: Hur är det egentligen med Set object = Nothing i VB6?
Som VB programmera är man lite bortskämd så tillvida att man varken i VB 6 eller VB.Net behöver bry sig särskilt mycket i de flesta fall.
-------
Om vi börjar med VB 6 så är det så att sätta till Nothing inte i sig frigör minne, utan det som händer är att man släpper referensen. Objektet finns kvar och eftersom vi nu saknar en referens så är det upp till objektet att rensa sig själv.
När det då gäller externa objekt så är dessa normalt implementerade med en räknare som håller reda på hur många referenser som finns till den. När den når noll (när alla refenser släppt) så är det normalt implementerat så att den då laddar ur sig från minnet automatiskt.
Ett viktigt undantag finns när det t.ex. gäller formulär i VB som man måste manuellt köra unload på annars så ligger de kvar i minnet så länge programmet körs. Dock så håller VB internt alltid reda på dessa så när man stänger ner sitt program så frigörs allt minne som upptagits av formulären.
Här avviker det igen mot externa objekt. Om nu det externa objektet inte laddar ur sig själv så har man problem, eftersom VB programmet inte kan hålla reda på externa objekt, så även när VB programmet slutat köra så kan externa objekt finnas kvar i minnet.
I samtliga fall är det så att själva variablens utrymme (de fåtal byte som pekaren tar upp) frigörs normalt sett direkt när variablens scope upphör. I vissa fall kan dock variabeln ligga aktiv fram tills dess att programmet avslutas. Oavsett så är det endast ett fåtal byte som anväds per pekare så i slutändan är det försvinnande lite om vi inte pratar miljontals variabler...
Så för att summera för VB 6 så behöver man bry sig om att ladda ur formulär, medan externa objekt sköter sig själv. I vilket fall som helst så är det städat och fint när programmet avslutas.
------
I VB.Net fungerar det lite annorlunda, dock inte jättestor skillnad.
Den "berömda" garbage collectorn håller reda på data som inte används och städar bort det när den anser att det inte längre behövs. Detta avser själva variabeln och även interna objekt. Externa objekt är det ingen skillnad mot tidigare.
Vad garbage collectorn innebär i praktiken är att en variabel faktiskt kan finnas kvar efter det att dess scope upphört eftersom GC tycker att det inte funnits anledning eller tid att städa ännu. Viss "pooling" effekt kan därför uppnås.
Intressant nog kan detta innebära att en variabel kan upphöra att existera innan dess scope är slut, om det enligt kompilatorn inte finns några läsningar eller skrivningar till den längre. Gör man därför t.ex. direkta minnesanrop mot en variabel så kan det innebära att man får konstig data, även om detta i sig skall vara ytterst sällsynt att man dels behöver göra detta och dels att GC släppt variablen samtidigt som dess utrymme utnyttjats igen.
Med andra ord, minnesoperationer måste ske på ett kontrollerat sätt och man skall inte försöka manipulera variablerna på egna på hittade omvägar eller kommandon. Så länge man följer regelboken så är det inga problem.
Så för att summera VB.Net så behöver man inte bry sig här heller, allting sker automagiskt... :-)
-------
Notera nu att detta ovan är en förenklad bild av verkligheten. Man kan naturligtvis diskutera detaljer om varje enskild del ovan. Principen är dock densamma. Konsekvenserna likaså.
Lycka till!
// Johan
PS.
I både VB 6 och .Net så tycker jag personligen att det är snyggt om man tar förvana att städa upp efter sig. Dels underlättar det att komma ihåg attt vara konsekvent när det gäller annan städning som t.ex. stängningar av databaskopplingar, men det underlättar också den dagen man behöver arbeta i ett annat språk där man måste ha koll på städningen. Och så visar man att man har koll på läget. :-)Sv: Hur är det egentligen med Set object = Nothing i VB6?
Set objRS = objConnection.Execute("select ditt, datt from någonstans")
' läs
objRS.Close
Set objRS = Nothing
Set objRS = objConnection.Execute("select somligt, annat from annorstädes")
' läs
objRS.Close
Set objRS = Nothing
Ifall man tar bort referensen till recordsetet så kommer det att hamna i objekt-poolen, och när man skapar ett nytt objekt så återanvänds objektet.
Ifall man inte tar bort referensen så kommer det nya objektet att skapas innan det gamla tas bort. Ifall det inte finns något sådant objekt i poolen sedan tidigare som kan återanvändas så måste ett helt nytt objekt skapas. Att skapa ett helt nytt objekt tar ungefär 100 gånger så lång tid som att återanvända ett objekt.