javascript - instance.invokeMethod 内存泄漏
问题描述
我通过 .invokeMethod 对 C# 进行了很多调用,而我的 GarbageCollector 似乎令人窒息。显然我不太了解 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>
我的 Razor 页面如下所示:
@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();
}
}
我的 GarbageCollector 很快就会出现“GC_MINOR: (Nursery full)”消息,而我的 System / JSArrayBufferData 看起来很大。从文档中,我可以收集到应该处理的对象,但是在这样的情况下它们也应该被处理吗?(在哪里?!)
(更新:好的,所以 System / JSArrayBufferData 总是很大,即使在运行 Blazor 示例时也是如此。所以我想这本身并没有任何指示......但这仍然对我没有帮助)
这是一个问题的原因是,当我尝试做任何有意义的事情时,GC VERY 经常会启动。这里的例子只是为了说明即使在最简单的情况下也会发生这种情况。
谢谢!
/托马斯
解决方案
这可能不起作用,并且作为对原始问题的评论的更完整建议添加。我会鼓励 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 中范围服务生命周期的官方文档。
希望这有帮助,请回来报告!
推荐阅读
- java - 如何设置弹出背景透明 Java Fx
- r - 根据 R 中的其他列值对行求和
- angular - matTooltipTouchGestures='off' 还会禁用非触摸小工具的工具提示
- php - 存储和显示富文本内容是否安全?
- c - C对象的对象转储中有哪些列?
- powershell - Powershell:Import-CSV - 如何选择特定单元格(即:A5、A10.A15)
- python - 比较数据框值错误中的 2 列
- c - 为什么在文件或结构中使用多个互斥锁?
- c# - C# - 如何为程序创建“保护进程”并确保它始终运行?
- php - WordPress:获取带有状态草稿并已发布的用户帖子数量