2017-10-15 108 views
0

我想追查我認爲與我如何使用MS債券有關的內存泄漏。特別是,由於在while循環內每次迭代都會生成'new'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循環上方並在循環內重用這些對象?

回答

1

如果生成的msg實例存儲在處理完一個請求後的任何位置,則可以保持該緩衝區處於活動狀態。

當使用綁定或blob類型字段時,msg實例可以引用底層InputBufferArraySegment

如果沒有這樣做,我已經與WinDBG extension command !gcroot運氣,找出什麼東西比我預期的存活時間長。如果!gcroot提供更多見解,但不是解決方案,請編輯這些問題的細節。