OK, I've done some exploration (I'm not a big fan of waiting for answers from Autodesk if I don't have to
), and I think I've figured it out.
The vla-object is an interface object that links the Lisp environment with the Autocad object model. You create or get vla-objects and assign them to AutoLisp variables; this allows you to interact with the Autocad object. So, in VLisp, there can be THREE items involved in any entity interaction: the entity itself, the interface object (vla-object), and the AutoLisp variable. All of these can be created/destroyed independently of the others.
Autolisp variables remain until they are set to nil, which happens automatically on function termination if the variable is local to that function. VLA-OBJECTs remain until they are vla-released or until they are garbage collected. All vla-objects that are orphaned - i.e., vla-objects that are not vla-released before their associated Autolisp variable is set to some other value (or nil) - are garbage collected. Witness:
Command: (setq x (vlax-get-acad-object))
#<VLA-OBJECT IAcadApplication 00af9594>
Command: (vlax-release-object x)
4
Command: (setq x (vlax-get-acad-object))
#<VLA-OBJECT IAcadApplication 00af9594>
Command: (setq y (vlax-get-acad-object))
#<VLA-OBJECT IAcadApplication 00af9594>
Command: (vlax-release-object x)
5
Command: (repeat 100 (setq x (vlax-get-acad-object)))
#<VLA-OBJECT IAcadApplication 00af9594>
Command: (vlax-release-object x)
104
Command: (gc)
nil
Command: (vlax-release-object y)
4
Therefore, it is not necessary to call vlax-release-object unless you trigger too many garbage collections. For example, in a routine such as the following, there's actually a string of vla-objects created and not released:
(defun sample:getCurrentTextStyleName ()
(vla-get-name
(vla-get-activeTextStyle
(vla-get-activeDocument
(vlax-get-acad-object)
) ;_ vla-get-activeDocument
) ;_ vla-get-activeTextStyle
) ;_ vla-get-name
) ;_ defun
However, it's no big deal. They'll be garbage-collected at the next gc, which happens automatically whenever it becomes necessary.
So, my take on things is that the vla-release-object is generally unnecessary, unless it causes a noticeable impact on performance, and doing explicit releases changes that.
I know that, from a purist point of view, it may be preferable to always use an explicit release, but I would argue that it is frequently better to limit code to functional pieces, rather than adding unnecessary pieces that may be technically more "correct". Limiting your code to "just the important parts", to whatever extents allowed by the language, is something I usually view as a good thing. Not only is it faster to write, it results in more-readable code. It's much easier to look at a function and say "Ah, that does that" if you don't have to trace through a lot of code added merely to satisfy implementation details of the language.
Garbage collection may be "slop" on some level, but if there's no reason to deal with mundane details such as memory management, then I say don't. Why waste time on code unless it serves a purpose? Strict memory-management can cause horrendous debugging headaches, as anyone struggling to learn C/C++ data structures can attest.
And, from a software-development point-of-view, it's actually perfectly OK (even desireable) to write the code "sloppy" to get it working, and get the problem-solving logic correct, then go back later and add details such as memory-management to improve performance if it proves necessary or desirable... Garbage-collection is kind of nice that way.
(Note - this does NOT imply that it's OK to forget to set your non-local AutoLisp variables to nil...)