【问题标题】:Memory management in COMCOM 中的内存管理
【发布时间】:2012-02-16 17:58:23
【问题描述】:

在COM服务器执行过程中分配一块内存,然后通过一个输出参数将该内存块传递给客户端是很常见的。然后,客户端有义务使用 CoTaskMemFree() 等方法释放该内存。

问题是,这块内存分配在哪里?假设 COM 服务器和 COM 客户端在不同的进程中,为了让客户端访问该内存块,它 应该 被分配在客户端的进程地址空间中。但这是真的吗?我听说 COM 有一个“Task Memory Allocator”。但我对此知之甚少。

只是一些疯狂的猜测:

首先是COM服务器根据COM客户端的请求分配内存,使用CoTaskMemAlloc()。

然后,COM 客户端获取那块内存,使用它,并使用 CoTaskMemFree() 释放它。

因此“任务内存分配器”必须同时跟踪客户端和服务器进程。否则,它将不知道谁(服务器)执行了内存分配操作以及应该给谁(客户端)该内存。然后,分配的内存会以某种方式注入到客户端的进程地址空间。

有人能解释一下这个话题吗?

【问题讨论】:

    标签: com


    【解决方案1】:

    嗯,“任务内存分配器”是一个 COM 拥有的分配器,它公开了那些 CoTaskMem* 函数。现在假设客户端和服务器在不同的进程中,服务器使用CoTaskMemAlloc()分配一个“out”参数。它如何到达客户端?

    具有编组功能的 COM 子系统可以做到这一点。服务器分配内存并从其 COM 方法实现中返回控制权。 COM 子系统现在必须将调用结果编组到客户端。它只是获取该内存的所有权并将其编组给客户端。客户端在其(客户端)堆上分配自己的块,数据被复制到客户端,服务器上的块被释放。客户端获得了区块的所有权,之后必须释放它,否则区块就会泄露。

    所以客户端和服务器地址空间总是分开的,不会发生直接的数据访问。每个都使用自己的内存分配器,编组在中间启动,使客户端分配内存并让服务器释放内存,以便客户端获得合法分配的块的所有权,而服务器释放它自己分配的块的所有权。

    所以对于客户端而言,它几乎看起来就像是服务器分配了内存并将其返回给客户端。一个值得注意的例外是允许逻辑地址不同 - 例如服务器在地址0x10001000 分配内存并将该地址与块一起返回。客户端不能保证在相同的逻辑地址获得块 - 地址将取决于客户端分配器。

    【讨论】:

      【解决方案2】:

      如果您使用 CoTaskMemAlloc 分配内存块,则该内存最终将使用默认的每进程堆 (source) 分配。

      使用 CoTaskMemAlloc 与任何其他分配器之间的区别在于,此分配是 COM 感知的,这意味着 COM 能够在需要时跨进程边界(例如通过复制内存)编组此内存.

      【讨论】:

        【解决方案3】:

        任务内存分配器在哪里分配内存块的问题是一个实现细节,我认为这与您了解无关。然而,重要的是,这个内存分配器为您提供了一个接口和机制,您可以通过它跨进程边界分配和取消分配内存。

        当你以某种机制分配内存时,无论是new还是CoTaskMemAlloc,都必须使用相应的释放机制。所以new 使用deleteCoTaskMemAlloc 使用CoTaskMemFree

        OLE 分配器将负责正确分配和释放内存,即使您在进程 X 中分配,传递给进程 Y 然后释放内存。

        关键是你使用相同的机制。

        【讨论】:

          猜你喜欢
          • 2011-11-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-30
          • 2011-07-25
          • 2012-09-19
          • 2011-01-30
          • 2012-08-27
          相关资源
          最近更新 更多