我通过.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(的项目中的信息量,但我会更多地研究这一点。
谢谢。