Scope of new ActiveXObject... when is it destructed?

I wrote a COM object in C++ and and it uses some resources.  Now in my JScript code I have fns like:

function DoSomething() {
     var oMyObj= new ActiveXObject( "MyApp.MyObject" );
     var nCnt= oMyObj.CountItems();
     return nCnt;
}

The problem is that the Browser does not seem to release the resouces until I close or refresh the webpage.  In my COM object, my destructor pops up a message box to indicate that it is destructing (and freeing the resources).  But that message box does not pop up as expected.    Commands like

       delete oMyObj;
or
       oMyObj= void;  // I've see oMyObj=nothing in VB...
or
       allowing the the object to go out of scope (end of function)

do not invoke the destructor.

For now, I added a oMyObj.Close() so that I could manually free up the resource.  But I'd rather know the exact rules of when the destructor will be called and do this right.  Can anyone help?

-- Dan
LVL 50
DanRollinsAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

cj_nepentheCommented:
Hi Dan,

"oMyObj = null" should release the reference to your object, but it's difficult to predict exactly when it'll be destoryed. JavaScript uses automatic garbage collection, so when the object is freed really depends on the implementation.
Sorry I can't be more help!  It's probably best to stick with the close() method approach.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
NetGrooveCommented:
Hello Dan,

one additional note.
If you write, like you did, a var clause in front of your object assignment, then is that object reference created locally to the lifetime of that block where it is defined, in your case is the block the function body block.
Without the var would the lifetime of the object be global for the page (window, document level).

Also releasing a reference to an object does not immediately invoke the destructor. It only calls the Release counter of the object to reduce the reference count to that object.

0
NetGrooveCommented:
Hey, perhaps you should invoke your destructor from the Release method call!
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

XxavierCommented:
"If you write, like you did, a var clause in front of your object assignment, then is that object reference created locally to the lifetime of that block where it is defined, in your case is the block the function body block."

    Yes the object is no longer accessible after the completion of the function call but that does not mean the resources (ie space in RAM) it had used is now available for use by the program, it has become garbage as cj_nepenthe pointed out.

0
DanRollinsAuthor Commented:
I added code like this (which I copied from ATLCOM.H) to my C++ object definition.

      ULONG InternalRelease()
      {
            AfxMessageBox("CMyObj Release");
            ATLASSERT(m_dwRef > 0);
            return _ThreadModel::Decrement(&m_dwRef);
      }
      void FinalRelease()
      {
            AfxMessageBox("CMyObj Final Release");
      }

FinalRelase is called when I close the browser.  Release is called many times -- but none of them when I'm expecting them!  Not at the end of the scope, and not after delete and not after obj=null

It is true that if I use (in JScript) {

      var oMyObj= null;
      function DoSomething() {
            oMyObj= new ActiveXObject( "MyApp.MyObject" );
      ...

That  I can minimize the number of times Release gets called (obviously when var is used inside of the function, a new instance is created each time the fn is called).  I found an MDSN INFO reference that describes how to force garbage collection in VBScript, version 1.1 by allocating a huge string -- but that is a total kludge.

It looks like I'll need to close the database connection after each use becasue I don't feel right about my customers needing to call Close() or Cleanup() functions all over the place.

-- Dan
0
XxavierCommented:
  With the var then there are certainly going to be multiple instances hanging around before garbage collection but I am not sure (prepared to be convinced otherwise) that removing the var reduces  the problem. Assigning an identifier to an object reults in that identifier being a pointer, (essentially), to that object so the statement in the function (no var)

         oMyObj= new ActiveXObject( "MyApp.MyObject" );

would result in a new object being created and the resources used would increase unless the new instance overwrote the old instance, but I am not sure it does this for suppose I had

       oMyObj= new ActiveXObject( "MyApp.MyObject" );
       oMyObj1=oMyObj;
       oMyObj= new ActiveXObject( "MyApp.MyObject" );

then what is oMyObj1 pointing to? Unless the implementation checks to see if the oldobject pointed to by oMyObj has no other references. My guess this is system dependent.
       

           
0
XxavierCommented:
Dam it muddled thinking oMyObj1 will point to the new object, but the point still stands resources will increase unless the old instance is overwritten, I am not sure this is always the case.
0
XxavierCommented:
I was right in the first place they do act as pure pointers to the resource. This results in a red background with the date in seconds in the text box. So reassigning the identifier can not clear the resource unless the implemtation can check to see if there are no other pointers to it, and it will have to wait for garbage collection.

<form name="F1">
  <input type="text" name="T1">
</form>
<script>
  obj=new Date()
  obj1=obj
  obj=document
  obj.bgColor="red"
  obj.F1.T1.value=obj1.getTime()
</script>

0
DanRollinsAuthor Commented:
No "magic bullet" solution that I was hoping to get, but verification of my fears.  

I ended up closing the database connection between calls.  I found that if I just keep one connection open, the opens and closes are very fast, so it does not seem to be a hardship.  I also added a Close() member function to allow a manual way to force closing when the resourse usage is tight (I can only have 10 concurrent connections with this runtime DBMS).

-- Dan
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.