microsoft / ClearScript

A library for adding scripting to .NET applications. Supports V8 (Windows, Linux, macOS) and JScript/VBScript (Windows).
https://microsoft.github.io/ClearScript/
MIT License
1.77k stars 148 forks source link

"RangeError: Array buffer allocation failed" when Executing "new Uint8Array()" #576

Closed DavidBal closed 5 months ago

DavidBal commented 5 months ago

Hi,

i have the following simplified code.

using (V8ScriptEngine v8ScriptEngine = new V8ScriptEngine())
{
    int length = 356_000_000;

    string code = """
        if(typeof(Host_Functions) !== "function"){
            globalThis.Host_Functions = {
                UInt8ArrayBuilder: (length) => {
                    return new Uint8Array(length);
                }
            }
        }
        """;

    v8ScriptEngine.Evaluate(code);

    ITypedArray<byte> jsTypedArray = v8ScriptEngine.Script.Host_Functions.UInt8ArrayBuilder(length);

    Console.WriteLine(jsTypedArray.Length);

    jsTypedArray.Dispose();

}

I am building for x86 (32bit). Here is my csprj file:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
      <TargetFrameworks>net7.0-windows7.0</TargetFrameworks>
      <RuntimeIdentifiers>win-x86</RuntimeIdentifiers>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
      <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.ClearScript" Version="7.4.5" />
  </ItemGroup>

</Project>

If i execute the code above i getting the following execption: RangeError: Array buffer allocation failed

The exception is thrown when the engines executes the new Uint8Array(...) for a large number, in this example 356000000 what should be something around 365MB.

It works for x64 but, but thats not an option at the moment.

Because of that i think the reason could be some kind of memory limitation for x86 processes. Could you please confirm that for me?

Best regards, David

ClearScriptLib commented 5 months ago

Hi @DavidBal,

That exception is thrown in the following situations:

  1. The requested allocation would exceed MaxArrayBufferAllocation.
  2. The standard calloc function failed to acquire a memory block of the requested size.

If you aren't specifying MaxArrayBufferAllocation, then the latter is most likely. Note that 365MB is a significant portion of the address space available to a 32-bit process, so even if sufficient total space is available, there may not be a contiguous free block of that size.

Good luck!

DavidBal commented 5 months ago

Hi @ClearScriptLib,

thank you for the quick answer.

MaxArrayBufferAllocation is not specified and is his default value ulong.MaxValue.

So it "must" be the calloc call that fails. I feared something like that...

Thanks again for your quick answer.

Best regards, David