#javascript #node.js #v8
#javascript #node.js #v8
Вопрос:
У меня есть приложение узла, которое отправляет исходный код JavaScript в виде строки рабочему потоку, который выполняет его в API виртуальной машины узла. Я делаю снимок только кучи рабочего потока. Это делается для обнаружения любых выделений строк в исходном коде JavaScript. Однако я получаю много неясных комментариев в виде строк, которые раздувают кучу.
Изначально я подозревал, что это связано с тем, как виртуальная машина узла выполняет код в виде строки, поэтому я прокомментировал часть своего кода VM, но я все еще получаю эти нежелательные строки. Возможно, это связано с использованием require()
и import
?
Мой код выглядит следующим образом. Опять же, app.js
просто передает исходный код в виде строки в мой рабочий поток, worker.mjs
. worker.mjs
будет запускать переданные строковые данные внутри изолированной среды виртуальной машины, а затем записывать их снимок кучи в файл.
// App.js file
const { Worker, isMainThread } = require('worker_threads');
if (isMainThread) {
// JavaScript source code passed as String.
let workerData = `
var nop = unescape("%u9090%u9090");
while (nop.length <= 0x100000/2) {nop = nop;}`;
const worker = new Worker('./worker.mjs', { workerData });
worker.once('message', (filename) => {
console.log(`worker heapdump: ${filename}`);
});
// Tell the worker to create a heapdump.
worker.postMessage('heapdump');
};
// worker.mjs
import { workerData, parentPort, threadId } from 'worker_threads';
import { createContext, runInContext } from 'vm';
import { writeHeapSnapshot, getHeapSnapshot } from 'v8';
parentPort.once('message', (message) => {
if (message === 'heapdump') {
const sandbox = {};
const strict = '"use strict";'
createContext(sandbox);
runInContext(strict workerData, sandbox, {timeout: 10000 });
parentPort.postMessage(writeHeapSnapshot());
}
});
Моя конечная цель — собрать все строки и объединенные строки, созданные только из исходного кода строки workerData
. В этом примере значение nop
переменной.
Но, как показано, в конкатенированной строке также так много пустых данных.
"encodingOps.ucs2.byteLength"@29509
"encodingOps.utf16le.byteLength"@29531
"encodingOps.latin1.byteLength"@29555
"encodingOps.ascii.byteLength"@29579
"encodingOps.base64.byteLength"@29603
"encodingOps.hex.byteLength"@29627
"module.exports.getModuleFromWrap"@39059
...
...
"internal/modules/package_json_reader.js"@10997
"internal/modules/esm/translators.js"@11001
"internal/modules/esm/transform_source.js"@11011
"internal/modules/esm/resolve.js"@11021
"internal/modules/esm/module_map.js"@11025
"internal/modules/esm/module_job.js"@11029
"internal/modules/esm/loader.js"@11033
"internal/modules/esm/get_source.js"@11043
"internal/modules/esm/get_format.js"
Модуль виртуальной машины позволяет компилировать и запускать код в контекстах виртуальной машины версии 8. Модуль виртуальной машины не является механизмом безопасности. Не используйте его для запуска ненадежного кода. https://nodejs.org/api/vm.html
Я понимаю, что виртуальная машина узла выполняет код в своем собственном контексте. Можно ли получить идентификатор контекста виртуальной машины, а затем отфильтровать моментальный снимок кучи для строк, находящихся в этом конкретном контексте? В этом случае мне нужна только nop
переменная. Я надеюсь на какой-то способ анализа JSON моментального снимка без использования chrome dev-tools
.
Ответ №1:
Возможно, это связано с использованием
require()
иimport
?
По сути, да. Вы хотели все строки, вы получаете все строки. JavaScript использует много строк. (Конкретный механизм импорта не имеет значения. Если вы выполните какой-либо код, вы увидите его строки / etc в моментальном снимке кучи.)
Можно ли получить идентификатор контекста виртуальной машины, а затем отфильтровать моментальный снимок кучи для строк, находящихся в этом конкретном контексте?
Нет, нет никакой связи между объектами кучи и контекстами.