12345678910111213141516171819202122232425262728293031323334353637 |
- <H1>COM Object Lifetime in JACOB</H1>
- <H2>introduction</H2>
- JACOB Version 1.7 implements a new
- <a href="JacobThreading.html">Threading Model</a> that is more compatible with COM apartments. There is also an incompatibility between the Java object
- lifetime model and that of COM objects. COM Objects live and die by their reference count, whereas Java objects are collected
- by the Garbage Collector (GC) based on algortihms that are hidden from the user.
- <H2>COM Object Lifetime in JACOB Prior to Version 1.7</H2>
- In version 1.6 and earlier, JACOB objects which wrapped COM objects had
- <code>finalize()</code> methods that would call a native
- <code>release</code> method which would call a COM
- <code>Release</code>.
- <p></p>
- This has many problems. For one thing, the GC may take a long time to kick in and resource consumption may grow. However,
- the more problematic issue is that finalizers are called from a separate thread, and, as was discussed in the
- <a href="JacobThreading.html">Threading Model</a>
- document, this can result in COM errors if the object is running in an STA. Even if the object is running in an MTA, the
- finalizer may decide to run after we have terminated the thread that holds the component, in which case we would get fatal
- errors and crashes.
- <H2>COM Object Lifetime in JACOB in Version 1.7</H2>
- In Version 1.7, all JACOB objects which wrap COM objects extend
- <code>com.jacob.com.JacobObject</code>. This object has some special code to register itself with a
- <code>com.jacob.com.ROT</code> object which represents a Running Object Table (ROT). This table maps a Thread to the set of JacobObjects created in that
- thread. Therefore, when you call
- <code>ComThread.Release()</code>, the ROT checks whether that thread has created any objects, and these objects are released by calling their native
- <code>release</code> method (which is public).
- <p></p>
- This lifetime management method ties the lifecycle to the thread's lifecycle rather than the GC. The JacobObject's still
- have finalizers, but they will typically not perform the native
- <code>release</code> since that has already been called. The native
- <code>release</code> methods were written such that you can call them multiple times without worrying - since they zero out the native pointer
- when called the first time.
- <p></p>
- If you choose to call
- <code>release</code> methods on your objects yourself, that is allowed. In that case, when the thread is released the release calls will be no-ops.
- <p></p>
- It becomes important for you to call
- <code>ComThread.Release()</code> on any thread before you allow it to exit, otherwise you may get some random crashes later on in your code.
|