COM Object Lifetime in JACOB

introduction(介绍)

JACOB Version 1.7 implements a new Threading Model 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. (JACOB 1.7版实现了新的线程模型,该模型与COM公寓更加兼容。 Java对象生存期模型与COM对象的生存期模型之间也不兼容。 COM对象按其引用计数生存和死亡,而Java对象由垃圾收集器(GC)根据对用户隐藏的算法收集。)

COM Object Lifetime in JACOB Prior to Version 1.7(1.7版之前的JACOB中的COM对象生存期)

In version 1.6 and earlier, JACOB objects which wrapped COM objects had finalize() methods that would call a native release method which would call a COM Release. (在1.6版或更早的版本中,包装COM对象的JACOB对象具有finalize()方法,该方法将调用本机发布方法,该方法将调用COM发布。)

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 Threading Model 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. (这有很多问题。一方面,GC可能需要很长时间才能投入使用,并且资源消耗可能会增加。但是,更成问题的问题是,终结器是从单独的线程中调用的,并且如线程模型文档中所讨论的,如果对象在STA中运行,则可能导致COM错误。即使对象在MTA中运行,终结器也可能在终止包含组件的线程之后决定运行,在这种情况下,我们将出现致命错误并崩溃。)

COM Object Lifetime in JACOB in Version 1.7(JACOB 1.7版中COM对象的生存时间)

In Version 1.7, all JACOB objects which wrap COM objects extend com.jacob.com.JacobObject. This object has some special code to register itself with a com.jacob.com.ROT 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 ComThread.Release(), the ROT checks whether that thread has created any objects, and these objects are released by calling their native release method (which is public). (在1.7版中,所有包裹COM对象的JACOB对象都扩展了com.jacob.com.JacobObject。该对象有一些特殊的代码可以向com.jacob.com.ROT对象注册,该对象代表一个运行对象表(ROT)。该表将一个Thread映射到在该线程中创建的JacobObjects集。因此,当您调用ComThread.Release()时,ROT会检查该线程是否创建了任何对象,并通过调用其本机释放方法(公共)来释放这些对象。)

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 release since that has already been called. The native release 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. (这种生命周期管理方法将生命周期与线程的生命周期联系在一起,而不是与GC联系在一起。 JacobObject仍具有终结器,但由于已被调用,它们通常不执行本机发行。编写本机发布方法的目的是,您可以多次调用它们而不必担心-因为它们在首次调用时会将本机指针清零。)

If you choose to call release methods on your objects yourself, that is allowed. In that case, when the thread is released the release calls will be no-ops. (如果您选择自己调用对象的释放方法,则允许这样做。在那种情况下,当线程被释放时,释放调用将是无操作的。)

It becomes important for you to call ComThread.Release() on any thread before you allow it to exit, otherwise you may get some random crashes later on in your code. (在允许任何线程退出之前,在任何线程上调用ComThread.Release()变得很重要,否则以后在代码中可能会导致一些随机崩溃。)