52 lines
2.6 KiB
HTML
52 lines
2.6 KiB
HTML
<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.
|