0

我正在尝试追踪我认为与我使用 MS Bond 的方式有关的内存泄漏。具体来说,由于在 while 循环内的每次迭代中都会生成“新的”ArraySegment 和 InputBuffer 对象,因此问题可能出在订阅者端。

在发布者方面,代码大致如下所示,我认为这里没有问题:

open ZeroMQ
open Bond
open Bond.Protocols
open Bond.IO.Unsafe

let bond = new BondStructs.SomeStruct()
let output = new OutputBuffer()
let writer = new CompactBinaryWriter<OutputBuffer>(output)

let ctx = new ZContext()
let sock = new ZSocket(ctx, ZSocketType.PUB)
sock.Bind "tcp://localhost:12345"

while true do

    // do work, populate bond structure
    Marshal.To(writer, bond)
    use frame = new ZFrame(output.Data.Array, output.Data.Offset, output.Data.Count)
    sock.Send frame
    output.position <- 0L

我认为问题出在订阅者方面,因为每次迭代都会生成新的 ArraySegment 和 InputBuffer 对象,并且 GC 无法正确清理。

open ZeroMQ
open Bond
open Bond.Protocols
open Bond.IO.Unsafe

let sock = new ZSocket(ctx, ZSocketType.SUB)
sock.SubscribeAll()
sock.SetOption(ZSocketOption.CONFLATE, 1) |> ignore
sock.Connect("tcp://localhost:12345")

while true do
    let zf = sock.ReceiveFrame()
    let segment = new ArraySegment<byte>(zf.Read())
    let input = new InputBuffer(segment)
    let msg = Unmarshal<Record>.From(input)
    zf.Close()

    // do work

有没有办法让我将 ArraySegment 和 InputBuffer 行推到 while 循环上方并在循环中重用这些对象?

4

1 回答 1

1

如果msg在处理一个请求后将结果实例存储在任何地方,则可以使缓冲区保持活动状态。

msg实例可以具有对基础的引用,或者InputBufferArraySegment使用绑定或 blob 类型字段时。

如果做不到这一点,我很幸运地使用了WinDBG 扩展命令!gcroot来弄清楚是什么让某些东西比我预期的更长寿。如果!gcroot提供更多见解,但不是解决方案,请将这些详细信息编辑到问题中。

于 2017-10-19T19:12:59.100 回答