V8 Изолирует — существует ли ограничение на количество экземпляров? Сбой в 4.7k экземплярах

#v8

#v8

Вопрос:

Я проверяю пределы версии 8 и количество экземпляров, которые она может создать, но я сталкиваюсь со следующей ошибкой. При этом используется около 18 ТБ виртуальной памяти и 3500 МБ реальной памяти. Ранее я запускал программы с объемом виртуальной памяти 120 ТБ, поэтому я не думаю, что ограничение виртуальной памяти ОС является проблемой. Возможно, V8 следует настроить по-другому? Я использую V8_COMPRESS_POINTERS. Мне интересно, может ли это быть проблемой (2 ^ 32 * 4676 = ~ 20 ТБ).

 // 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;
}
 

Ответ №1:

Похоже, вы, возможно, нашли предел 😉

Честно говоря, из предоставленных вами выходных данных неясно, что именно происходит, то есть откуда берется ограничение. Это может быть ограничение, не связанное с V8, где-то в вашей системе. Версия 8 не имеет встроенного фиксированного максимального количества изолятов; она позволит вам создавать новые изоляты до тех пор, пока для этого достаточно ресурсов.

Ожидается, что при включенном сжатии указателей каждый Isolate резервирует область виртуальной памяти объемом 4 ГБ при запуске. Однако не похоже, что проблема заключается в исчерпании виртуальной памяти, поэтому я бы предположил, что отключение сжатия указателей не поможет.

Чтобы лучше понять, что происходит, может оказаться полезным получить трассировку стека для неудачной проверки (с отладочной сборкой).


РЕДАКТИРОВАТЬ для обновления:
я могу повторить. Сбой — это вызов mprotect , вызываемый (косвенно) из v8::internal::IsolateAllocator::CommitPagesForIsolate . В этот момент cat /proc/$PID/maps | wc -l возвращает 65531 для процесса и sysctl vm.max_map_count выдает мне 65530. Итак, как я и подозревал, это не ограничение V8; это максимум ядра Linux по умолчанию для отображаемых областей памяти, которые разрешено иметь процессу. Вы можете увеличить это ограничение, если вам нужно больше. (Хотя я несколько сомневаюсь в полезности тысяч изолятов в одном и том же процессе одновременно — если они непустые, вы скоро столкнетесь с другими ограничениями памяти: например, 4K изолятов * 10 МБ (что не так много для нетривиальной программы) — это уже 40 ГБ потребления физической памяти.)

Примечание: компиляция V8 действительно проста, если следовать инструкциям на https://v8.dev/docs/embed ; единственная деталь, которая нуждается в корректировке, — это то, что вам нужно std=c 14 в настоящее время.

Комментарии:

1. Я отредактировал вопрос, чтобы предоставить полный программный код, который довольно короткий. Не могли бы вы попробовать? Скомпилировать V8 было довольно сложно, и я мог потратить несколько часов, ничего не добившись: (