Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 缓慢的内存释放(refcounted结构)-我的解决方法是一种好方法吗?_Delphi_Delphi 2007_Refcounting - Fatal编程技术网

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

Delphi 缓慢的内存释放(refcounted结构)-我的解决方法是一种好方法吗?,delphi,delphi-2007,refcounting,Delphi,Delphi 2007,Refcounting,在我的程序中,我可以加载一个目录:ICatalog 这里的目录包含许多引用计数结构(iItem、iElement、IRules等的Icollections) 当我想切换到另一个目录时, 我加载一个新目录 但是,自动释放以前的ICatalog实例需要时间,将我的应用程序冻结2秒或更长时间 我的问题是: 我想将旧的(并且不再使用的)ICatalog实例的发布推迟到另一个线程 我还没有测试过它,但我打算创建一个新线程: ErazerThread.OldCatalog := Catalog; // ol

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

这里的目录包含许多引用计数结构(iItem、iElement、IRules等的Icollections)

当我想切换到另一个目录时, 我加载一个新目录 但是,自动释放以前的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.
这样,我希望在线程中发布,而我的应用程序不会 比林不再结冰了

它是否安全(和良好实践)?

您是否有已经使用类似方法执行发布的现有代码的示例?

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

我会让这样的线程阻塞某个线程安全队列(*),并将接口作为iunknowns推送到该队列中

但是请注意,如果释放涉及内存管理器使用的锁(如全局heapmanager锁),那么这是徒劳的,因为主线程将在第一次heapmanager访问时阻塞

对于具有每线程池的heapmanager,在一个线程中分配多个项目并在不同的线程中释放可能会阻碍(小)块算法的合并和重用

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


(*)最简单的方法是将其添加到tthreadlist中,并使用tevent发出添加元素的信号。

另一件需要注意的事情是,您的对象可能与创建它的线程有某种关联。您是否使用了探查器并找出了免费代码花费如此长时间的原因?堆操作本身可能不会造成问题,除非您正在释放1.8 gb内存,每次释放100字节。@WarrenP使用采样探查器,并使用OutputDebugString(“采样打开”)包装发行版;(和关闭),我发现95,05%的时间发生在ntdll.dll中。。。这对我没有什么用处。。(那么,对我的可执行文件中剩余的4.54%的分析对优化是否有意义呢?)?这是关于接口分配的。但我不知道要慢多少。@DamienD:我很惊讶内存分配在ntdll.dll中占用了这么多时间。一定是换了很多东西?你有多少物理内存?我明白你的意思,但是关于线程和低级内存管理,我是,嗯,一个初学者。。。如果我错了,请更正:全局heapmanager锁可能是由threadsafe对象引起的?(我的意思是,关键部分的使用?)线程安全对象在释放时传递给memorymanager。memorymanager可以从多个线程调用,因此具有锁。也许我应该这样总结答案:“如果遍历树、引用计数和析构函数是主要的减速因素,那么推线程可能会有所帮助。如果是在heapmanager中释放的工作(或者是对COM的调用,如果它们是COM对象),则可能不会”尝试它。在我的情况下,推到一个线程没有帮助(请参阅我的问题下的评论)。谢谢你解释原因。