在我的程序中,我可以加载目录:ICatalog
这里的目录包含很多引用结构(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.
这样,我希望释放发生在线程中,而我的应用程序则不会 不再被卡住了。
安全(并且是良好的做法)吗?
您是否有已经使用类似方法执行发布的现有代码示例?
最佳答案
我会让这样的线程阻塞在某个线程安全队列(*)上,并将接口(interface)作为未知数推送到该队列中。
但是请注意,如果释放触及内存管理器使用的锁(例如全局堆管理器锁),那么这是徒劳的,因为您的主线程将在第一次堆管理器访问时阻塞。
对于每个线程池的堆管理器,在一个线程中分配许多项并在不同的线程中释放它可能会阻碍(小) block 算法的合并和重用。
我仍然认为,如果实现得当,您描述的方式通常是合理的。但 这是从理论角度来看的,表明可能存在通过堆管理器从第二个线程到主线程的链接。
(*) 最简单的方法是将其添加到 tthreadlist 并使用 tevent 来表示元素已添加。
关于delphi - 缓慢的内存释放(引用结构)-我的解决方法是一个好方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7822870/