如何在德尔福开始构建可搜索的垃圾收集器(2009-2010)

Bra*_*bra 6 delphi garbage-collection delphi-2009 delphi-2010

我正在寻找一种方法来控制我在用Delphi编写的应用程序中创建的所有业务对象.

正如关于Embarcadero的EDN(http://edn.embarcadero.com/article/28217)的文章所述,基本上有三种方法可以做到这一点.我最感兴趣的是使用接口的最后一个.这样,当业务对象不再被应用程序中的任何地方引用时,它将被处理内存(稍后我将回到这一部分).

在创建新的业务对象时,最好先询问新的对象管理器是否已在程序中先前获取它,从而避免需要从数据库中重新获取它.我已经将内存中的业务对象,所以为什么不使用那个呢?因此,我需要内存中可用对象的列表可以搜索(快速).

提供的代码使用"TObject数组"来存储收集的对象,一旦达到一定数量,这对于搜索对象列表不会非常有效.我必须将其更改为TObjectList或某种二进制可搜索树.这里最好的选择是什么?我已经在http://www.ibrtses.com/delphi/binarytree.html找到了一些有用的代码(我认为).JCL在二叉树上没有东西吗?

我该如何处理该树中的"业务对象"和"业务对象列表"?作为列表一部分的业务对象是否会在树中引用两次?

关于处理对象:我还想为该业务对象设置某种TTL(生存时间),在一定时间后强制重新获取.如果引用计数器降到0,我仍然希望将对象保留一段时间,如果程序仍然需要它在TTL内.这意味着我需要排序一些线程监视器来循环对象列表(或树)以监视要删除的对象.

我还遇到了Boehm垃圾收集器DLL(http://codecentral.embarcadero.com/Download.aspx?id=21646).

简而言之,将我的"对象管理器"作为EDN文章中提供的源代码的基础是明智的吗?我想要将对象存储在哪种列表中?我该如何处理列表中的对象列表?我是否应该将我的对象保留在内存中一段时间​​并通过线程监视器进行处理?

我的推理是否正确?在开始编码之前有任何建议,想法或评论吗?也许一些新想法融入我的代码?

顺便说一下,一旦有些聪明的头脑想出来,我会很乐意分享结果,让别人受益.

日Thnx.

Jim*_*eth 3

如果您使用接口进行引用计数,然后将它们放入某种集合中,那么您将始终拥有对它们的引用。如果您的目标是“垃圾收集”,那么您只需要其中之一,但如果有必要,您当然可以同时使用两者。

听起来您真正想要的是业务对象缓存。为此,您将需要使用新的通用TDictionary集合之一。您可能想要做的是拥有一个 TDictionary 集合,每个对象类型对应一个 TDictionary。您可以将主 TDictionary 键入枚举,甚至可以键入对象本身的类型(我没有尝试过,但它可能会起作用。)如果您使用 GUID 作为唯一标识符,那么您可以将它们全部放入一个 TDictionary。

使用接口实现每个业务对象。您不需要使用智能指针,因为您正在设计业务对象并且可以从 TInterfacedObject 派生它们。然后只通过它的接口引用它,这样就可以进行引用计数。

如果您想让缓存过期,那么您需要在对象上有某种时间戳,每次从缓存中检索对象时都会更新该时间戳。然后,当缓存超过某个特定大小时,您可以修剪早于特定时间戳的所有内容。当然,这需要遍历整个缓存才能做到这一点。

由于您正在组合接口和集合,因此如果您有对对象的引用(通过其接口),并且它在缓存清理期间被修剪,那么该对象将保持活动状态,直到引用消失。这为您提供了额外的安全性。当然,如果您仍在使用该引用,那么这意味着您将引用保留了很长时间而没有从缓存中检索它。在这种情况下,您可能还希望在读取或写入属性时更新时间戳。。。这在很大程度上取决于您将如何使用业务对象。

就重新获取而言,您只想在从缓存中检索到早于重新获取限制的对象时才执行此操作。这样,如果在再次使用它之前对其进行修剪,您就不会浪费数据库行程。

您可能会考虑在每个表中只包含最后修改时间。然后,当您从缓存中获取对象时,只需检查内存中的时间与数据库中的时间即可。如果该对象自上次检索以来已发生更改,您可以更新它。

我将限制更新对象仅在从缓存中检索它们时进行。这样,您就不太可能在使用对象时对其进行修改。如果您正在从对象中读取数据,而对象发生变化,则可能会产生一些非常奇怪的行为。有几种方法可以解决这个问题,具体取决于您如何使用东西。

关于使用接口的警告,不应同时让对象和接口引用同一个对象。这样做可能会导致引用计数出现问题,并导致在您仍然拥有对象引用时释放对象。

我确信对此会有一些反馈,因此请选择听起来最适合您的解决方案。。。。

当然,既然我已经写了所有这些,我会建议您查看某种业务对象框架。RemObjects有一个很好的框架,我相信还有其他框架。