V8 Isolates - 实例数量有限制吗?在 4.7k 实例时崩溃

V8 Isolates - is there a limit to the number of instances? Crashes at 4.7k instances

我正在测试V8的限制,以及它可以创建多少个实例,但是我遇到了以下错误。这使用了大约 18TB 的虚拟内存和 3500MB 的实际内存。我以前 运行 有 120TB 虚拟内存的程序,所以我认为 OS 虚拟内存限制不是问题。 也许 V8 应该以不同的方式配置? 我正在使用 V8_COMPRESS_POINTERS。我想知道这是否是个问题 (2^32*4676 = ~20TB)。

// stdout
...
Isolate: 4674
Isolate: 4675
Isolate: 4676

# Fatal error in , line 0
# Check failed: ReleasePages(page_allocator_, reinterpret_cast<void*>(region_.begin()), old_size, region_.size()).
#
#FailureMessage Object: 0x7fffe09bae80
#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include "libplatform/libplatform.h"
#include "v8.h"

int main(int argc, char *argv[]) {
    std::cout << "Loading V8..." << std::endl;

    // Initialize V8.
    v8::V8::InitializeICUDefaultLocation(argv[0]);
    v8::V8::InitializeExternalStartupData(argv[0]);
    std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
    v8::V8::InitializePlatform(platform.get());
    v8::V8::Initialize();

    v8::Isolate::CreateParams create_params;
    create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();

    v8::Isolate *isolates[20000];
    for (int i = 0; i < 20000; i++) {
        std::cout << "Isolate: " << i << std::endl;

        v8::Isolate *isolate = v8::Isolate::New(create_params);
        isolates[i] = isolate;
    }

    return 0;
}

听起来您可能已经找到了极限 ;-)

公平地说,从您提供的输出来看,并不清楚到底发生了什么,即限制来自何处。它可能是您系统中某处与 V8 无关的限制。 V8 没有内置固定的最大 Isolate 数量;只要有足够的资源,它就会让你创建新的 Isolates。

预计在启用指针压缩的情况下,每个 Isolate 都会在启动时保留 4GB 的虚拟内存区域。听起来虚拟内存耗尽并不是这里的问题,所以我猜关闭指针压缩不会有帮助。

为了更好地理解正在发生的事情,获取失败检查的堆栈跟踪(使用调试版本)可能会很有见地。


编辑更新:
我可以复制。失败的是从 v8::internal::IsolateAllocator::CommitPagesForIsolate 调用(间接)调用 mprotect。那时,进程的 cat /proc/$PID/maps | wc -l returns 65531,sysctl vm.max_map_count 给了我 65530。所以正如我所怀疑的,这不是 V8 限制;它是 Linux 内核默认允许进程拥有的映射内存区域的最大值。如果您需要更多,可以提高该限制。 (尽管我有点质疑同时在同一进程中使用数千个 Isolates 的用处——如果它们非空,您很快就会 运行 进入其他内存限制:例如 4K isolates * 10MB(这是对于一个重要的程序来说并不多)已经是 40GB 的物理内存消耗。)

旁注:如果您按照 https://v8.dev/docs/embed; 中的说明进行编译 V8 真的很容易,唯一需要调整的细节是现在您需要 std=c++14