instance.invokeMethod memory leak



我通过.invokeMethod对C#进行了大量调用,我的垃圾收集器似乎令人窒息。显然我不太了解Javascript/Blazor互操作内存管理,所以希望你们中的一个人可以提供帮助。

我正在设置 window.requestAnimationFrame 以回调到 c#。JS如下所示:

<script type="text/javascript">
window.anim = {
start: function (instance) {
console.log('start');
return window.requestAnimationFrame(function (timestamp) { anim.callback(instance); });
},
callback: function (instance) {
instance.invokeMethod('IncrementCount');
var callbackId = window.requestAnimationFrame(function (timestamp) { anim.callback(instance); });
},
stop: function (callbackId) {
window.cancelAnimationFrame(callbackId);
}
};
</script>

我的剃刀页面如下所示:

@page "/counter"
@inject IJSRuntime JSRuntime;
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var dotNetReference = DotNetObjectReference.Create(this);
await JSRuntime.InvokeAsync<string>("window.anim.start", dotNetReference);
}
}
[JSInvokable("IncrementCount")]
public void IncrementCount()
{
currentCount++;
StateHasChanged();
}
}

我的垃圾收集器很快就出现了"GC_MINOR:(托儿所满("消息,我的系统/JSArrayBufferData看起来很大。 从文档中,我可以收集到应该释放对象,但是在这种情况下也应该释放它们吗?(在哪里?!

(更新:好的,所以系统/JSArrayBufferData总是巨大的,即使在运行Blazor示例时也是如此。所以我想这本身没有任何迹象。但这仍然对我没有帮助(

这是一个问题的原因是,一旦我尝试做任何有意义的事情,GC 就会启动。这里的例子只是为了说明即使在最简单的情况下也会发生这种情况。

谢谢!

/托马斯

这可能不起作用,并且正在作为更完整的建议添加到对原始问题的评论中。我会鼓励OP评论这有多有效,并鼓励其他人纠正我错的地方,以便我可以更多地了解这一点。

由于"IJSRuntime"填满了内存,这背后的想法是,运行时的生存期范围可能比应有的时间长得多,并且由于 Blazor 是一个有状态框架,因此状态随之而来。

要尝试的是使用OwningComponentBase将 JS 运行时的范围强制实施到组件的生存期、Blazor Server 中的连接生存期或 Blazor WASM 中的单一实例。设置应该只需要几行代码。在 Razor 文件的顶部:

@inherits OwningComponentBase

然后在@code块中:

@code {
// Property for the runtime, NOT injected here    
public IJSRuntime Runtime { get; set; } 
// Sets up the Runtime as a scoped service, so it will release and be available 
// for Garbage Collection when the component is torn down
protected override void OnInitialized()
{
Runtime = ScopedServices.GetRequiredService<IJSRuntime>();
}
}

如果我的想法是正确的,这应该有助于内存管理。我鼓励其他可能对这个主题更了解的人也评论或编辑这篇文章。

这是在有关 Blazor 中作用域服务生存期的官方文档之后。

希望这有帮助,请报告!

因此,在进一步调查之后,我相当确定我误解了内存泄漏的单声道 GC 消息。

看起来毕竟没有泄漏,但 GC 只是让您知道它正在清理。为大雁追逐道歉!:)

我仍然担心GC在触发这篇文章(https://github.com/jackpotdk/BlazorGame(的项目中的信息量,但我会更多地研究这一点。

谢谢。

最新更新