11

我尝试使用 TensorFlowSharp 构建一个小的 tensorflow 应用程序,有时我会收到此异常:

托管调试助手“CallbackOnCollectedDelegate”

对于函数TensorFlowSharp!TensorFlow.TFBuffer+BufferReleaseFunc::Invoke

我试图找出它的含义,但我没有完全理解这些解释。这是引发异常的代码部分:

var graph = new TFGraph();
var model = File.ReadAllBytes(ModelsFile);
graph.Import(model, "");

有人知道我应该怎么做才能防止这种异常吗?

布鲁诺

4

2 回答 2

2

我只看到这个错误的一个很好的候选者,即 Buffer.cs 中的委托。但是 Miguel 已经在 7 月 27 日修复了这个错误,差异就在这里。因此,请确保更新您的副本。如果您是从 Nuget 获得的,请确保您至少拥有 1.30 版

于 2017-09-16T08:58:28.503 回答
2

我认为这是 TensorflowSharp 中的一个错误。

该错误看起来像是 CLR 代码中通常不一致的访问冲突(通常仅在重负载或随机尝试次数时发生)。引用微软文档

callbackOnCollectedDelegate如果委托作为函数指针从托管代码编组到非托管代码,并且在委托被垃圾回收后将回调放置在该函数指针上,则会激活托管调试助手 (MDA) 。

当创建函数指针并暴露给非托管代码的委托被垃圾回收时,会发生这种类型的错误。当非托管组件试图调用函数指针时,它会产生访问冲突。失败似乎是随机的,因为它取决于垃圾收集发生的时间。

解决问题可能很困难,因为一旦委托被封送为非托管函数指针,垃圾收集器就无法跟踪其生命周期。相反,需要在非托管函数指针的生命周期内保留对委托的引用。为此,必须在 TensorFlowShapr 的代码(或您的代码)中识别收集到的错误委托。

您还可以启用 gcUnmanagedToManaged MDA,以在每次回调到运行时之前强制进行垃圾收集。这将通过确保垃圾收集总是在回调之前发生来消除垃圾收集引入的不确定性。一旦您知道收集了哪些委托,请更改您的代码以在编组的非托管函数指针的生命周期内在托管端保留对该委托的引用。

所以,我想最好将此报告给图书馆的制造商。

于 2017-09-14T05:49:28.793 回答