慢速内存释放(refcounted结构) - 我的解决方法是一个好方法吗?

时间:2011-10-19 14:28:43

标签: delphi delphi-2007 refcounting

在我的程序中,我可以加载目录:ICatalog

这里的目录包含许多refcounted结构(Itemlections of IItems,IElements,IRules等)

当我想换到另一个目录时, 我加载了一个新目录 但是以前的ICatalog实例的自动释放需要时间,冻结我的应用程序2秒或更长时间。

我的问题是:

我想将旧的(不再使用的)ICatalog实例的发布推迟到另一个线程。

我还没有测试过,但我打算用:

创建一个新线程
ErazerThread.OldCatalog := Catalog; // old catalog refcount jumps to 2
Catalog := LoadNewCatalog(...);     // old catalog refcount =1
ErazerThread.Execute;               //just set OldCatalog to nil.

这样,我希望在线程中发布,而我的应用程序不会 蜜蜂已经冻结了。

安全(和良好做法)是否安全? 您是否已经使用类似方法获取现有代码的示例?

2 个答案:

答案 0 :(得分:2)

看起来不错,但不要直接调用线程的Execute方法;这将在当前线程中运行线程对象的代码,而不是线程对象创建的线程。请改为呼叫StartResume

答案 1 :(得分:2)

我会让这样的线程阻塞在某些线程安全队列(*)上,并推送接口以iunknowns的形式释放到该队列中。

但是请注意,如果释放触及内存管理器使用的锁(如全局heapmanager锁),那么这是徒劳的,因为你的mainthread将阻塞第一个heapmanager访问。

使用每个线程池的堆管理器,在一个线程中分配许多项并在不同的线程中释放它可能会阻碍(小)块算法的合并和重用。

我仍然认为你描述的方式在正确实施时通常是合理的。但 这是从理论的角度来看,表明可能存在通过heapmanager从第二个线程到主线程的链接。

(*)最简单的方法是将它添加到tthreadlist并使用tevent来表示已添加元素。