Initial commit
This commit is contained in:
51
JacobComLifetime.html
Normal file
51
JacobComLifetime.html
Normal file
@@ -0,0 +1,51 @@
|
||||
<H1>COM Object Lifetime in JACOB</H1>
|
||||
<p>
|
||||
<H2>introduction</H2>
|
||||
<p>
|
||||
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>
|
||||
<p>
|
||||
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>
|
||||
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>
|
||||
<p>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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.
|
||||
Reference in New Issue
Block a user