1

I do use Global/Public Variables sparingly and only if it’s rewarding enough in many ways.

From what I can understand, the moment a variable is declared then the computer reserves a specific memory space for it for later use.

And if I got it right, a variable which is only declared to have a scope within a specific procedure, when the procedure ends, so is also the life of that variable. In other words the memory space which was allocated to that variable gets released/freed.

To my main question:

  1. Are there any ways to release/free the memory space which was allocated to a Global (Public) variable when it was declared?

Some research, reflections and sub-questions:

a) I have done some googling and seen people suggest placing an “End Statement” at a desired location within the code. Does this really release/free the memory space which was allocated to the Globally/Publicly declared variable? Or does this only “purge” or “reset” the variable to carry no assigned value or object at all (in other words the memory space which was allocated to the variable when the variable was declared is still allocated to it)?

b) I have also seen people set a Globally/Publicly declared variable equal to Nothing or Empty. But same question here. Does this really release/free the memory space which was allocated to the Globally/Publicly declared variable? Or does this only “purge” or “reset” the variable to carry no assigned value or object at all (in other words the memory space which was allocated to the variable when the variable was declared is still allocated to it)?

c) Does “Deleting” or “Killing” a Global (Public) variable release or free the memory space which was allocated to the variable when it was declared? Or does this only “purge” or “reset” the variable to carry no assigned value or object at all (in other words the memory space which was allocated to the variable when the variable was declared is still allocated to it)?

SweDentan
  • 67
  • 8
  • 1
    You cannot control when the memory is actually freed. It will happen automatically sometime after the variable goes out of scope. – Rory Oct 19 '20 at 12:10
  • Thanks @Rory for your reply. So what you're saying is that the only possible way to free the memory space which was allocated for a specific Global Variable, is for that Global Variable to go out of scope? – SweDentan Oct 19 '20 at 12:43
  • @Rory That is [profoundly untrue](https://stackoverflow.com/a/19038890/11683) for VBA. – GSerg Oct 19 '20 at 12:49
  • @GSerg Yes, in one very specific situation. Bit of an overstatement, no? :) – Rory Oct 19 '20 at 12:52
  • 1
    @Rory No, in all situations. There is no "some time after" at all, there is either "immediately" (if it was the last reference) or "none at all" (if it wasn't). – GSerg Oct 19 '20 at 12:53
  • @GSerg You're talking specifically about *object* references, but I still disagree with you. In my experience there is no guarantee that memory will actually be freed at the precise moment that the reference counter reaches 0, or that a variable goes out of scope. – Rory Oct 19 '20 at 13:25
  • Why are you asking this question? – freeflow Oct 19 '20 at 13:38
  • @Rory It is possible that a sloppy programmer violated the [COM principles](https://learn.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-release#remarks) and wrote a class that does not `delete this` when its reference count goes to zero. It is also possible that you were using the wrong tools for monitoring where the memory goes, or misinterpreted their result. Or, quite likely, you had a circular reference situation and the objects were finally destroyed when it was broken. In any case, if deterministic destruction does not happen, something is wrong. – GSerg Oct 19 '20 at 14:39
  • @GSerg Again, you are assuming we are talking about Objects, which is not necessarily the case. Also, your answer below seems to be in broad agreement with what I said, so I'm not really clear on what your point is. – Rory Oct 19 '20 at 14:55

1 Answers1

3

VB6/VBA uses deterministic approach to destroying objects. Each object stores number of references to itself. When the number reaches zero, the object is destroyed.

The way to destroy an object is to make sure that no object variables refer to it.

  • If an object is referenced by just one global variable, setting that variable to Nothing will both clear the variable's contents (it's no longer pointing to an object) and destroy the object, releasing its memory.
  • If the object is referenced by other variables too, setting the global variable to Nothing will only clear the contents of the variable (it's no longer pointing to an object), but the object will remain until all other references to it are set to Nothing.

An object variable itself occupies the size of a pointer (LongPtr, 4 or 8 bytes). By setting that variable to Nothing you fill these 4 or 8 bytes with zeroes, but you do not stop the variable from occupying these 4 or 8 bytes - nor can you.

Similarly, with non-object variables, setting them to anything at all only changes the content of the fixed amount of bytes that they occupy, but never deletes these bytes.

The only exception are dynamically sized arrays that you can Erase and reclaim the memory allocated for the array (but the pointer-sized array variable will still remain and will point to no array, that is, all its 4 or 8 bytes will be filled with zeroes).

To reiterate, in no case can you reclaim the space allocated for the variables themselves. That only happens when you exit the scope where they are declared - which, in case of global variables, is when the program terminates. You can only reclaim space taken by things that the variables point to.

GSerg
  • 76,472
  • 17
  • 159
  • 346
  • I got you @GSerg, Big Thank You! It isn't possible in any way to free the memory which the Global variables themselves occupy unless it goes out of scope (= the program terminates). But you can free the memory which a Global variable is pointing to only if it’s pointing to an object or a dynamic array according to the conditions explained in your reply. For the concerned, please also see when to declare "Global variables"” & or just “Pass” them in this [discussion](https://stackoverflow.com/questions/46431764/ms-excel-vba-is-it-faster-to-use-public-variables-or-pass-variables-between-sub) – SweDentan Oct 27 '20 at 10:09