2014-02-27 54 views
2

我有一個執行WMI查詢的程序,然後將數據轉換回到陸地數據結構(使用方法here)。每隔一段時間,go的GC就會出現,並將一些看起來隨機的內存部分燒燬到0 s,從而導致可怕的破壞。go的COM調用通過GC收集其數據,調零使用的內存

我想弄清楚究竟是什麼導致了這個問題,我相信下一步是瞭解COM調用過程中會發生什麼。我現在的理解是:

  1. 呼叫與WMI查詢COM從過程
  2. 操作系統執行查詢,並將結果寫入到由過程
  3. 該位置從返回擁有一些內存位置COM電話,然後我可以訪問和序列化

這是關於發生了什麼? Windows如何選擇該內存位置,使其不覆蓋現有數據?

+0

COM對象通常分配在堆上。之後,他們被引用計數。該位置由正常的運行時堆選擇。 –

+0

通常情況下,對象不會被GC'd(並覆蓋),直到它們不再被代碼引用。那裏有一些參考計數問題。 – sharptooth

+0

現在似乎是一個問題,因爲不像你們中的一些人所建議的那樣圍繞從COM返回的對象指針。我已經用最新的研究更新了github問題:https://github.com/mattn/go-ole/issues/13#issuecomment-36314577 – mjibson

回答

1

每個COM對象都使用AddRef()和Release()引用計數。也許你需要一個額外的AddRef()來保持它更長的時間。

我從示例代碼中看到,有很多被拒絕的發佈調用。這很好,因爲我們希望在main的結尾釋放對象。在你的程序中,你可能希望延遲釋放更長的時間(但是,我不知道去哪,或者推遲什麼)

+0

我會測試ref參數,看看它是否是問題所在。不過,我懷疑這是它的原因,因爲如果我禁用去GC(或編譯和運行一個32位去應用程序),然後一切工作正常。 – mjibson

+0

Do go對象是否引用了它們在GC上釋放的COM對象?如果是這樣的話(1)也許go對象需要引用它來保持它 - 例如,如果COM對象是引用go對象的唯一東西,那麼go GC可能不知道它。 (2)也許還需要額外的AddRef,並且GC'd對象不應該是最後的版本。 –

+0

參考計數似乎不是問題。刪除釋放呼叫,然後添加AddRef調用後,問題保持不變。 – mjibson

相關問題