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
。
我正在测试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
。