У меня есть проект Wasm для обработки изображений, который применяет различные алгоритмы бинаризации к данному изображению.Один из этих алгоритмов генерировал эту ошибку, когда я запускал ее:
Uncaught abort("Cannot enlarge memory arrays to size 17100800 bytes (OOM). Either
(1) compile with -s TOTAL_MEMORY=X with X higher than the current value 16777216,
(2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or
(3) if you want malloc to return NULL (0)
instead of this abort, compile with -s ABORTING_MALLOC=0 ") at Error
После компиляции с "-s ALLOW_MEMORY_GROWTH=1"
алгоритм не выдает ошибку в Chrome, но сделал изображение черным.Запуск его второй раз подряд дал эту ошибку:
Uncaught RuntimeError: memory access out of bounds
При первом запуске в Edge 42.17134.1.0
я получаю эту ошибку:
SCRIPT5147: The ArrayBuffer is detached.
Интересно, что удаление этой опции и замена ее на "-s TOTAL_MEMORY=512MB"
устранило проблему.
Поэтому мой вопрос таков:ALLOW_MEMORY_GROWTH=1
Предположим, во время выполнения, чтобы автоматически расширить память кучи и почти заменить TOTAL_MEMORY?Мне не нравится идея заблокировать во время компиляции максимальный объем памяти, который может использовать мое приложение.Протестировано с Chrome 73.0.3683.103
/ 74.0.3729.108 (Official Build) (64-bit)
и Firefox 66.0.3 (64-bit)
.
Редактировать Мне удалось изолировать проблему с помощью следующего кода.
Скомпилировано для отладки:
em++ -O0 -o ./dist/doxaWasm.js doxaWasm.cpp -std=c++1z -s WASM=1 -s NO_EXIT_RUNTIME=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['writeAsciiToMemory']" -g4 --source-map-base http://localhost:8080/ -s ALLOW_MEMORY_GROWTH=1
Фрагмент кода C ++:
extern "C"
{
void EMSCRIPTEN_KEEPALIVE Initialize(uint8_t* data, const int width, const int height)
{
// Large enough to force a reallocation.
// If there is no reallocation, everything works.
std::vector<int64_t> integral_image1(width*height*10);
data[0] = 123;
}
}
Фрагмент кода Javascript:
...
var size = width * height;
var heapPtr = Module._malloc(size);
var data = new Uint8ClampedArray(Module.HEAPU8.buffer, heapPtr, size);
... // Populate 'data' with 8bit grayscale based on canvas ImageData
Module._Initialize(data.byteOffset, width, height);
console.log(data[0]); // Equals 123 if there is no reallocation