-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Closed
Labels
arch-wasmWebAssembly architectureWebAssembly architecturearea-GC-monoos-browserBrowser variant of arch-wasmBrowser variant of arch-wasm
Milestone
Description
MONO_WASM: Out of memory
at System.MulticastDelegate.RemoveImpl(Delegate value)
at System.Delegate.Remove(Delegate source, Delegate value)
at Sample.ParentClass.remove_PropertyChanged(PropertyChangedEventHandler value)
at Sample.ChildClass.Dispose()
at Sample.TestClass.DisposeObjects()
at Sample.TestClass.__Wrapper_DisposeObjects_19325221(JSMarshalerArgument* __arguments_buffer)
Error: Out of memory
at marshal_exception_to_js (https://localhost:8000/_framework/dotnet.runtime.js:2384:18)
at invoke_sync_jsexport (https://localhost:8000/_framework/dotnet.runtime.js:3571:15)
at Object.bound_fn_0V (https://localhost:8000/_framework/dotnet.runtime.js:4626:13)
at Object.JSExport_DisposeObjects (https://dotnet/JSExport/DisposeObjects:4:55)
at https://localhost:8000/main.js:20:16
Probably related #107215
Repro
I'm able to reproduce it on latest Net10 main, but customer is reporting similar issues on Net8.
using System;
using System.Runtime.InteropServices.JavaScript;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Collections.Generic;
#pragma warning disable CS8632
namespace Sample;
public partial class TestClass
{
private static readonly ParentClass _parent = new();
private static readonly HashSet<ChildClass> _objects = [];
public static int Main(string[] args)
{
return 0;
}
[JSExport]
public static string AllocateObjects(int count)
{
for (int i = 0; i < count; i++)
{
var child = new ChildClass(_parent);
_objects.Add(child);
}
return GC.GetTotalMemory(forceFullCollection: false).ToString();
}
[JSExport]
public static void DisposeObjects()
{
foreach (var child in _objects)
{
child.Dispose();
}
}
}
public sealed class ChildClass : IDisposable
{
private readonly ParentClass _parent;
private readonly byte[] _junk = new byte[250_000];
public ChildClass(ParentClass parent)
{
_parent = parent;
_parent.PropertyChanged += OnPropertyChanged;
}
public void Dispose()
{
_parent.PropertyChanged -= OnPropertyChanged;
GC.SuppressFinalize(this);
}
private void OnPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
}
}
public sealed class ParentClass
{
public event PropertyChangedEventHandler? PropertyChanged;
public void NotifyChilderen()
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Foo"));
}
}import { dotnet, exit } from './_framework/dotnet.js'
try {
const { getAssemblyExports, runMain } = await dotnet
.withElementOnExit()
.withExitOnUnhandledError()
.create();
await runMain("Wasm.Browser.Sample", []);
const library = await getAssemblyExports("Wasm.Browser.Sample");
const testClass = library.Sample.TestClass;
console.log("Start allocating objects...");
const allocatedBytes = testClass?.AllocateObjects(3890);
console.log(`Allocated ${allocatedBytes} bytes`);
console.log("Disposing allocated objects...");
testClass?.DisposeObjects();
}
catch (err) {
exit(2, err);
}Metadata
Metadata
Assignees
Labels
arch-wasmWebAssembly architectureWebAssembly architecturearea-GC-monoos-browserBrowser variant of arch-wasmBrowser variant of arch-wasm