缓慢的内存释放(引用结构)-我的解决方法是一个好方法吗?
在我的程序中,我可以加载一个目录: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.
这样,我希望释放发生在线程中,而我的应用程序不会 不再被冻结了。
它安全(并且是良好的做法)吗?
您是否有已经使用类似方法执行发布的现有代码示例?
in my program i can load a Catalog: ICatalog
a Catalog here contains a lot of refcounted structures (Icollections of IItems, IElements, IRules, etc.)
when I want to change to another catalog,
I load a new Catalog
but the automatic release of the previous ICatalog instance takes time, freezing my application for 2 second or more.
my question is :
I want to defer the release of the old (and no more used) ICatalog instance to another thread.
I've not tested it already, but I intend to create a new thread with :
ErazerThread.OldCatalog := Catalog; // old catalog refcount jumps to 2
Catalog := LoadNewCatalog(...); // old catalog refcount =1
ErazerThread.Execute; //just set OldCatalog to nil.
this way, I expect the release to occur in the thread, and my application not
beeing freezed anymore.
Is it safe (and good practice) ?
Do you have examples of existing code already perfoming release with a similar method ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我会让这样的线程阻塞在一些线程安全队列(*)上,并将接口作为 iunknowns 释放到该队列中。
但请注意,如果释放触及内存管理器使用的锁(例如全局堆管理器锁),那么这是徒劳的,因为您的主线程将在第一次堆管理器访问时阻塞。
对于每个线程池的堆管理器,在一个线程中分配许多项并在不同的线程中释放它可能会阻碍(小)块算法的合并和重用。
我仍然认为,如果实施得当,您描述的方式通常是合理的。但
这是从理论角度来看的,表明可能存在通过堆管理器从第二个线程到主线程的链接。
(*) 最简单的方法是将其添加到 tthreadlist 并使用 tevent 来发出已添加元素的信号。
I would let such thread block on some threadsafe queue(*), and push the interfaces to release into that queue as iunknowns.
Note however that if the releasing touches a lock that your memory manager uses (like a global heapmanager lock), then this is futile, since your mainthread will block on the first heapmanager access.
With a heapmanager with per thread pools, allocating many items in one thread and releasing it in a different thread might frustrate coalescing and reuse of (small) blocks algorithms.
I still think the way you describe is generally sound when implemented properly. But
this is from a theoretic perspective to show that there might be a link from the 2nd thread to the mainthread via the heapmanager.
(*) Simplest way is to add it to a tthreadlist and use tevent to signal that an element was added.
看起来不错,但不要直接调用线程的 Execute 方法;它将在当前线程而不是线程对象创建的线程中运行线程对象的代码。请改为调用
Start
或Resume
。That looks OK, but don't call the thread's
Execute
method directly; that will run the thread object's code in the current thread instead of the one that the thread object creates. CallStart
orResume
instead.