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

发布于 2024-12-11 05:18:42 字数 573 浏览 0 评论 0原文

在我的程序中,我可以加载一个目录: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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

阳光①夏 2024-12-18 05:18:42

我会让这样的线程阻塞在一些线程安全队列(*)上,并将接口作为 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.

小清晰的声音 2024-12-18 05:18:42

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

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. Call Start or Resume instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文