Skip to content

V8

كود المصدر: lib/v8.js

الوحدة node:v8 تكشف عن واجهات برمجة تطبيقات خاصة بإصدار V8 المضمن في الثنائي Node.js. يمكن الوصول إليها باستخدام:

js
const v8 = require('node:v8');

v8.cachedDataVersionTag()

تمت إضافتها في: v8.0.0

إرجاع عدد صحيح يمثل علامة إصدار مشتقة من إصدار V8، وعلامات سطر الأوامر، وميزات وحدة المعالجة المركزية المكتشفة. هذا مفيد لتحديد ما إذا كانت vm.Script cachedData buffer متوافقة مع هذه النسخة من V8.

js
console.log(v8.cachedDataVersionTag()); // 3947234607
// القيمة التي يتم إرجاعها بواسطة v8.cachedDataVersionTag() مشتقة من V8
// الإصدار وعلامات سطر الأوامر وميزات وحدة المعالجة المركزية المكتشفة. اختبر أن القيمة
// يتم تحديثها بالفعل عند تبديل العلامات.
v8.setFlagsFromString('--allow_natives_syntax');
console.log(v8.cachedDataVersionTag()); // 183726201

v8.getHeapCodeStatistics()

تمت إضافتها في: v12.8.0

احصل على إحصائيات حول الكود والبيانات الوصفية الخاصة به في الكومة، راجع V8 GetHeapCodeAndMetadataStatistics API. تُرجع كائنًا بالخصائص التالية:

js
{
  code_and_metadata_size: 212208,
  bytecode_and_metadata_size: 161368,
  external_script_source_size: 1410794,
  cpu_profiler_metadata_size: 0,
}

v8.getHeapSnapshot([options])

[السجل]

الإصدارالتغييرات
الإصدار 19.1.0دعم الخيارات لتكوين لقطة الذاكرة المؤقتة.
الإصدار 11.13.0تمت الإضافة في: الإصدار 11.13.0
  • options <الكائن>

    • exposeInternals <منطقي> إذا كان صحيحًا، فسيتم عرض الأجزاء الداخلية في لقطة الذاكرة المؤقتة. افتراضي: false.
    • exposeNumericValues <منطقي> إذا كان صحيحًا، فسيتم عرض القيم الرقمية في الحقول الاصطناعية. افتراضي: false.
  • إرجاع: <stream.Readable> Readable يحتوي على لقطة الذاكرة المؤقتة V8.

يقوم بإنشاء لقطة من ذاكرة V8 المؤقتة الحالية وإرجاع Readable Stream يمكن استخدامه لقراءة التمثيل التسلسلي JSON. تم تصميم تنسيق دفق JSON هذا لاستخدامه مع أدوات مثل Chrome DevTools. مخطط JSON غير موثق وخاص بمحرك V8. لذلك، قد يتغير المخطط من إصدار V8 إلى آخر.

يتطلب إنشاء لقطة ذاكرة مؤقتة ذاكرة تبلغ حوالي ضعف حجم الذاكرة المؤقتة في وقت إنشاء اللقطة. هذا يؤدي إلى خطر إنهاء عمليات OOM للعملية.

يعد إنشاء لقطة عملية متزامنة تحظر حلقة الأحداث لفترة تعتمد على حجم الذاكرة المؤقتة.

js
// طباعة لقطة الذاكرة المؤقتة إلى وحدة التحكم
const v8 = require('node:v8');
const stream = v8.getHeapSnapshot();
stream.pipe(process.stdout);

v8.getHeapSpaceStatistics()

[السجل]

الإصدارالتغييرات
الإصدار 7.5.0دعم القيم التي تتجاوز نطاق عدد صحيح غير موقع 32 بت.
الإصدار 6.0.0تمت الإضافة في: الإصدار 6.0.0

إرجاع إحصائيات حول مساحات ذاكرة V8 المؤقتة، أي المقاطع التي تشكل ذاكرة V8 المؤقتة. لا يمكن ضمان ترتيب مساحات الذاكرة المؤقتة ولا توفر مساحة ذاكرة مؤقتة حيث يتم توفير الإحصائيات عبر وظيفة V8 GetHeapSpaceStatistics وقد تتغير من إصدار V8 إلى آخر.

القيمة التي يتم إرجاعها عبارة عن مجموعة من الكائنات التي تحتوي على الخصائص التالية:

json
[
  {
    "space_name": "new_space",
    "space_size": 2063872,
    "space_used_size": 951112,
    "space_available_size": 80824,
    "physical_space_size": 2063872
  },
  {
    "space_name": "old_space",
    "space_size": 3090560,
    "space_used_size": 2493792,
    "space_available_size": 0,
    "physical_space_size": 3090560
  },
  {
    "space_name": "code_space",
    "space_size": 1260160,
    "space_used_size": 644256,
    "space_available_size": 960,
    "physical_space_size": 1260160
  },
  {
    "space_name": "map_space",
    "space_size": 1094160,
    "space_used_size": 201608,
    "space_available_size": 0,
    "physical_space_size": 1094160
  },
  {
    "space_name": "large_object_space",
    "space_size": 0,
    "space_used_size": 0,
    "space_available_size": 1490980608,
    "physical_space_size": 0
  }
]

v8.getHeapStatistics()

[السجل]

الإصدارالتغييرات
v7.5.0يدعم القيم التي تتجاوز نطاق الأعداد الصحيحة غير الموقعة 32 بت.
v7.2.0تمت إضافة malloced_memory و peak_malloced_memory و does_zap_garbage.
v1.0.0تمت الإضافة في: v1.0.0

يُرجع كائنًا بالخصائص التالية:

total_heap_size قيمة total_heap_size هي عدد البايتات التي خصصتها V8 للكومة. يمكن أن ينمو هذا إذا كانت used_heap بحاجة إلى مزيد من الذاكرة.

total_heap_size_executable قيمة total_heap_size_executable هي الجزء من الكومة الذي يمكن أن يحتوي على تعليمات برمجية قابلة للتنفيذ، بالبايت. يتضمن ذلك الذاكرة المستخدمة بواسطة التعليمات البرمجية المجمعة بـ JIT وأي ذاكرة يجب أن تظل قابلة للتنفيذ.

total_physical_size قيمة total_physical_size هي الذاكرة الفعلية الفعلية المستخدمة بواسطة كومة V8، بالبايت. هذا هو مقدار الذاكرة الملتزم بها (أو قيد الاستخدام) بدلاً من المحجوزة.

total_available_size قيمة total_available_size هي عدد بايتات الذاكرة المتاحة لكومة V8. تمثل هذه القيمة مقدار الذاكرة الإضافية التي يمكن أن تستخدمها V8 قبل أن تتجاوز حد الكومة.

used_heap_size قيمة used_heap_size هي عدد البايتات التي تستخدمها حاليًا كائنات JavaScript الخاصة بـ V8. هذه هي الذاكرة الفعلية المستخدمة ولا تتضمن الذاكرة التي تم تخصيصها ولكن لم يتم استخدامها بعد.

heap_size_limit قيمة heap_size_limit هي الحد الأقصى لحجم كومة V8، بالبايت (إما الحد الافتراضي، الذي تحدده موارد النظام، أو القيمة التي تم تمريرها إلى الخيار --max_old_space_size).

malloced_memory قيمة malloced_memory هي عدد البايتات التي تم تخصيصها من خلال malloc بواسطة V8.

peak_malloced_memory قيمة peak_malloced_memory هي ذروة عدد البايتات التي تم تخصيصها من خلال malloc بواسطة V8 خلال عمر العملية.

does_zap_garbage هي قيمة منطقية 0/1، مما يدل على ما إذا كان الخيار --zap_code_space ممكنًا أم لا. هذا يجعل V8 يكتب فوق قمامة الكومة بنمط بت. يزداد حجم RSS (حجم المجموعة المقيمة) لأنه يلامس باستمرار جميع صفحات الكومة وهذا يجعلها أقل عرضة للاستبدال بواسطة نظام التشغيل.

number_of_native_contexts قيمة native_context هي عدد السياقات ذات المستوى الأعلى النشطة حاليًا. تشير الزيادة في هذا الرقم بمرور الوقت إلى تسرب الذاكرة.

number_of_detached_contexts قيمة detached_context هي عدد السياقات التي تم فصلها ولم يتم جمعها بواسطة القمامة بعد. يشير هذا الرقم غير الصفري إلى احتمال تسرب الذاكرة.

total_global_handles_size قيمة total_global_handles_size هي حجم الذاكرة الإجمالي لمقابض V8 العالمية.

used_global_handles_size قيمة used_global_handles_size هي حجم الذاكرة المستخدمة لمقابض V8 العالمية.

external_memory قيمة external_memory هي حجم ذاكرة مخازن المصفوفات والسلاسل الخارجية.

js
{
  total_heap_size: 7326976,
  total_heap_size_executable: 4194304,
  total_physical_size: 7326976,
  total_available_size: 1152656,
  used_heap_size: 3476208,
  heap_size_limit: 1535115264,
  malloced_memory: 16384,
  peak_malloced_memory: 1127496,
  does_zap_garbage: 0,
  number_of_native_contexts: 1,
  number_of_detached_contexts: 0,
  total_global_handles_size: 8192,
  used_global_handles_size: 3296,
  external_memory: 318824
}

v8.queryObjects(ctor[, options])

أضيف في: الإصدار 22.0.0، 20.13.0

[مستقر: 1 - تجريبي]

مستقر: 1 الاستقرار: 1.1 - تطوير نشط

  • ctor <Function> المُنشئ الذي يمكن استخدامه للبحث في سلسلة النموذج الأولي (prototype chain) لترشيح الكائنات المستهدفة في الذاكرة المؤقتة (heap).

  • options <undefined> | <Object>

    • format <string> إذا كانت القيمة 'count'، فسيتم إرجاع عدد الكائنات المطابقة. إذا كانت القيمة 'summary'، فسيتم إرجاع مصفوفة تحتوي على سلاسل تلخيصية للكائنات المطابقة.
  • الإرجاع: {number|Array

يشبه هذا واجهة برمجة التطبيقات queryObjects() console API التي توفرها وحدة تحكم Chromium DevTools. يمكن استخدامه للبحث عن الكائنات التي تحتوي على المُنشئ المطابق في سلسلة النموذج الأولي الخاصة بها في الذاكرة المؤقتة بعد جمع البيانات المهملة الكامل (garbage collection)، وهو ما قد يكون مفيدًا لاختبارات الانحدار الخاصة بتسرب الذاكرة (memory leak regression tests). لتجنب النتائج المفاجئة، يجب على المستخدمين تجنب استخدام واجهة برمجة التطبيقات هذه على المُنشئات التي لا يتحكمون في تنفيذها، أو على المُنشئات التي يمكن استدعاؤها من قبل أطراف أخرى في التطبيق.

لتجنب التسريبات العرضية، لا تُرجع واجهة برمجة التطبيقات هذه مراجع أولية للكائنات التي تم العثور عليها. بشكل افتراضي، تُرجع عدد الكائنات التي تم العثور عليها. إذا كانت options.format هي 'summary'، فسيتم إرجاع مصفوفة تحتوي على تمثيلات سلسلة موجزة لكل كائن. تتشابه الرؤية التي توفرها واجهة برمجة التطبيقات هذه مع ما توفره لقطة الذاكرة المؤقتة (heap snapshot)، بينما يمكن للمستخدمين توفير تكلفة التسلسل والتحليل وتصفية الكائنات المستهدفة مباشرة أثناء البحث.

يتم تضمين الكائنات التي تم إنشاؤها في سياق التنفيذ الحالي فقط في النتائج.

js
const { queryObjects } = require('node:v8');
class A { foo = 'bar'; }
console.log(queryObjects(A)); // 0
const a = new A();
console.log(queryObjects(A)); // 1
// [ "A { foo: 'bar' }" ]
console.log(queryObjects(A, { format: 'summary' }));

class B extends A { bar = 'qux'; }
const b = new B();
console.log(queryObjects(B)); // 1
// [ "B { foo: 'bar', bar: 'qux' }" ]
console.log(queryObjects(B, { format: 'summary' }));

// Note that, when there are child classes inheriting from a constructor,
// the constructor also shows up in the prototype chain of the child
// classes's prototype, so the child classes's prototype would also be
// included in the result.
console.log(queryObjects(A));  // 3
// [ "B { foo: 'bar', bar: 'qux' }", 'A {}', "A { foo: 'bar' }" ]
console.log(queryObjects(A, { format: 'summary' }));
js
import { queryObjects } from 'node:v8';
class A { foo = 'bar'; }
console.log(queryObjects(A)); // 0
const a = new A();
console.log(queryObjects(A)); // 1
// [ "A { foo: 'bar' }" ]
console.log(queryObjects(A, { format: 'summary' }));

class B extends A { bar = 'qux'; }
const b = new B();
console.log(queryObjects(B)); // 1
// [ "B { foo: 'bar', bar: 'qux' }" ]
console.log(queryObjects(B, { format: 'summary' }));

// Note that, when there are child classes inheriting from a constructor,
// the constructor also shows up in the prototype chain of the child
// classes's prototype, so the child classes's prototype would also be
// included in the result.
console.log(queryObjects(A));  // 3
// [ "B { foo: 'bar', bar: 'qux' }", 'A {}', "A { foo: 'bar' }" ]
console.log(queryObjects(A, { format: 'summary' }));

v8.setFlagsFromString(flags)

أضيف في: v1.0.0

يمكن استخدام طريقة v8.setFlagsFromString() لتعيين علامات سطر الأوامر V8 برمجيًا. يجب استخدام هذه الطريقة بحذر. قد يؤدي تغيير الإعدادات بعد بدء تشغيل الجهاز الظاهري إلى سلوك غير متوقع، بما في ذلك الأعطال وفقدان البيانات؛ أو قد لا تفعل شيئًا ببساطة.

يمكن تحديد خيارات V8 المتاحة لإصدار من Node.js عن طريق تشغيل node --v8-options.

الاستخدام:

js
// طباعة أحداث GC إلى stdout لمدة دقيقة واحدة.
const v8 = require('node:v8');
v8.setFlagsFromString('--trace_gc');
setTimeout(() => { v8.setFlagsFromString('--notrace_gc'); }, 60e3);

v8.stopCoverage()

أضيف في: v15.1.0, v14.18.0, v12.22.0

تسمح طريقة v8.stopCoverage() للمستخدم بإيقاف تجميع التغطية الذي بدأ بواسطة NODE_V8_COVERAGE، بحيث يمكن لـ V8 تحرير سجلات عدد التنفيذ وتحسين التعليمات البرمجية. يمكن استخدام هذا بالتزامن مع v8.takeCoverage() إذا أراد المستخدم جمع التغطية حسب الطلب.

v8.takeCoverage()

أضيف في: v15.1.0, v14.18.0, v12.22.0

تسمح طريقة v8.takeCoverage() للمستخدم بكتابة التغطية التي بدأها NODE_V8_COVERAGE على القرص عند الطلب. يمكن استدعاء هذه الطريقة عدة مرات خلال دورة حياة العملية. في كل مرة سيتم فيها إعادة تعيين عداد التنفيذ وكتابة تقرير تغطية جديد في الدليل المحدد بواسطة NODE_V8_COVERAGE.

عندما تكون العملية على وشك الخروج، سيتم كتابة تغطية أخيرة واحدة على القرص ما لم يتم استدعاء v8.stopCoverage() قبل خروج العملية.

v8.writeHeapSnapshot([filename[,options]])

[السجل]

الإصدارالتغييرات
v19.1.0دعم الخيارات لتكوين لقطة الذاكرة المؤقتة.
v18.0.0سيتم الآن طرح استثناء إذا تعذر كتابة الملف.
v18.0.0اجعل رموز الخطأ التي تم إرجاعها متسقة عبر جميع الأنظمة الأساسية.
v11.13.0أضيف في: v11.13.0
  • filename <string> مسار الملف حيث سيتم حفظ لقطة الذاكرة المؤقتة V8. إذا لم يتم تحديده، فسيتم إنشاء اسم ملف بالنمط 'Heap-${yyyymmdd}-${hhmmss}-${pid}-${thread_id}.heapsnapshot'، حيث سيكون {pid} هو PID لعملية Node.js، وسيكون {thread_id} هو 0 عند استدعاء writeHeapSnapshot() من مؤشر ترابط Node.js الرئيسي أو معرف مؤشر ترابط عامل.

  • options <Object>

    • exposeInternals <boolean> إذا كانت true، فاعرض المكونات الداخلية في لقطة الذاكرة المؤقتة. افتراضي: false.
    • exposeNumericValues <boolean> إذا كانت true، فاعرض القيم الرقمية في الحقول الاصطناعية. افتراضي: false.
  • إرجاع: <string> اسم الملف حيث تم حفظ اللقطة.

ينشئ لقطة من الذاكرة المؤقتة V8 الحالية ويكتبها في ملف JSON. الغرض من هذا الملف هو استخدامه مع أدوات مثل Chrome DevTools. مخطط JSON غير موثق ومحدد لمحرك V8، وقد يتغير من إصدار V8 إلى آخر.

تعتبر لقطة الذاكرة المؤقتة خاصة بمعزل V8 واحد. عند استخدام مؤشرات ترابط العامل، لن تحتوي لقطة الذاكرة المؤقتة التي تم إنشاؤها من المؤشر الرئيسي على أي معلومات حول العمال، والعكس صحيح.

يتطلب إنشاء لقطة ذاكرة مؤقتة ذاكرة بحجم ضعف حجم الذاكرة المؤقتة تقريبًا في وقت إنشاء اللقطة. هذا يؤدي إلى خطر إنهاء قتلة OOM للعملية.

يعد إنشاء لقطة عملية متزامنة تحظر حلقة الأحداث لفترة تعتمد على حجم الذاكرة المؤقتة.

js
const { writeHeapSnapshot } = require('node:v8');
const {
  Worker,
  isMainThread,
  parentPort,
} = require('node:worker_threads');

if (isMainThread) {
  const worker = new Worker(__filename);

  worker.once('message', (filename) => {
    console.log(`worker heapdump: ${filename}`);
    // الآن احصل على تفريغ الذاكرة المؤقتة للمؤشر الرئيسي.
    console.log(`main thread heapdump: ${writeHeapSnapshot()}`);
  });

  // أخبر العامل بإنشاء تفريغ للذاكرة المؤقتة.
  worker.postMessage('heapdump');
} else {
  parentPort.once('message', (message) => {
    if (message === 'heapdump') {
      // قم بإنشاء تفريغ للذاكرة المؤقتة للعامل
      // وأرجع اسم الملف إلى الأصل.
      parentPort.postMessage(writeHeapSnapshot());
    }
  });
}

v8.setHeapSnapshotNearHeapLimit(limit)

أُضيف في: v18.10.0, v16.18.0

[مستقر: 1 - تجريبي]

مستقر: 1 الاستقرار: 1 - تجريبي

تعتبر واجهة برمجة التطبيقات (API) عديمة الفائدة إذا تم تعيين --heapsnapshot-near-heap-limit بالفعل من سطر الأوامر أو إذا تم استدعاء واجهة برمجة التطبيقات أكثر من مرة. يجب أن يكون limit عددًا صحيحًا موجبًا. راجع --heapsnapshot-near-heap-limit لمزيد من المعلومات.

واجهة برمجة تطبيقات التسلسل (Serialization API)

توفر واجهة برمجة تطبيقات التسلسل (Serialization API) وسائل لتسلسل قيم JavaScript بطريقة متوافقة مع خوارزمية استنساخ HTML المنظمة.

التنسيق متوافق مع الإصدارات السابقة (أي آمن للتخزين على القرص). قد تؤدي قيم JavaScript المتساوية إلى إخراج مُسلسل مختلف.

v8.serialize(value)

أُضيف في: v8.0.0

يستخدم DefaultSerializer لتسلسل value في مخزن مؤقت.

سيتم طرح ERR_BUFFER_TOO_LARGE عند محاولة تسلسل كائن ضخم يتطلب مخزنًا مؤقتًا أكبر من buffer.constants.MAX_LENGTH.

v8.deserialize(buffer)

أُضيف في: v8.0.0

يستخدم DefaultDeserializer مع الخيارات الافتراضية لقراءة قيمة JS من المخزن المؤقت.

الفئة: v8.Serializer

تمت إضافتها في: v8.0.0

new Serializer()

يقوم بإنشاء كائن Serializer جديد.

serializer.writeHeader()

يكتب رأسًا، يتضمن إصدار تنسيق التسلسل.

serializer.writeValue(value)

يقوم بتسلسل قيمة JavaScript ويضيف التمثيل المتسلسل إلى المخزن المؤقت الداخلي.

يطرح هذا خطأ إذا تعذر تسلسل value.

serializer.releaseBuffer()

إرجاع المخزن المؤقت الداخلي المخزن. يجب عدم استخدام هذا المسلسل بمجرد تحرير المخزن المؤقت. تؤدي استدعاء هذه الطريقة إلى سلوك غير محدد إذا فشلت كتابة سابقة.

serializer.transferArrayBuffer(id, arrayBuffer)

يميز ArrayBuffer على أنه تم نقل محتوياته خارج النطاق. قم بتمرير ArrayBuffer المطابق في سياق إلغاء التسلسل إلى deserializer.transferArrayBuffer().

serializer.writeUint32(value)

اكتب عددًا صحيحًا غير موقع 32 بت خامًا. للاستخدام داخل serializer._writeHostObject() مخصص.

serializer.writeUint64(hi, lo)

اكتب عددًا صحيحًا غير موقع 64 بت خامًا، مقسمًا إلى أجزاء عالية ومنخفضة 32 بت. للاستخدام داخل serializer._writeHostObject() مخصص.

serializer.writeDouble(value)

اكتب قيمة number لـ JS. للاستخدام داخل serializer._writeHostObject() مخصصة.

serializer.writeRawBytes(buffer)

اكتب بايتات خام في المخزن المؤقت الداخلي للمسلسل. سيتطلب إلغاء التسلسل طريقة لحساب طول المخزن المؤقت. للاستخدام داخل serializer._writeHostObject() مخصصة.

serializer._writeHostObject(object)

يتم استدعاء هذه الطريقة لكتابة نوع من كائن المضيف، أي كائن تم إنشاؤه بواسطة روابط C ++ الأصلية. إذا لم يكن من الممكن تسلسل object، فيجب طرح استثناء مناسب.

هذه الطريقة غير موجودة في فئة Serializer نفسها ولكن يمكن توفيرها بواسطة الفئات الفرعية.

serializer._getDataCloneError(message)

يتم استدعاء هذه الطريقة لإنشاء كائنات خطأ سيتم طرحها عندما لا يمكن استنساخ كائن.

تستخدم هذه الطريقة بشكل افتراضي مُنشئ Error ويمكن تجاوزها في الفئات الفرعية.

serializer._getSharedArrayBufferId(sharedArrayBuffer)

يتم استدعاء هذه الطريقة عندما يكون المسلسل على وشك تسلسل كائن SharedArrayBuffer. يجب أن تُرجع معرّف عدد صحيح غير موقع 32 بت للكائن، باستخدام نفس المعرّف إذا تم بالفعل تسلسل SharedArrayBuffer هذا. عند إلغاء التسلسل، سيتم تمرير هذا المعرّف إلى deserializer.transferArrayBuffer().

إذا تعذر تسلسل الكائن، فيجب طرح استثناء.

هذه الطريقة غير موجودة في فئة Serializer نفسها ولكن يمكن توفيرها بواسطة الفئات الفرعية.

serializer._setTreatArrayBufferViewsAsHostObjects(flag)

يشير إلى ما إذا كان سيتم التعامل مع كائنات TypedArray و DataView ككائنات مضيفة، أي تمريرها إلى serializer._writeHostObject().

الصنف: v8.Deserializer

أُضيف في: v8.0.0

new Deserializer(buffer)

ينشئ كائن Deserializer جديدًا.

deserializer.readHeader()

يقرأ ويتحقق من صحة رأس (بما في ذلك إصدار التنسيق). قد يرفض، على سبيل المثال، تنسيقًا سلكيًا غير صالح أو غير مدعوم. في هذه الحالة، يتم طرح Error.

deserializer.readValue()

يزيل تسلسل قيمة JavaScript من المخزن المؤقت ويعيدها.

deserializer.transferArrayBuffer(id, arrayBuffer)

يميز ArrayBuffer على أنه تم نقل محتوياته خارج النطاق. قم بتمرير ArrayBuffer المقابل في سياق التسلسل إلى serializer.transferArrayBuffer() (أو قم بإرجاع id من serializer._getSharedArrayBufferId() في حالة SharedArrayBuffer).

deserializer.getWireFormatVersion()

يقرأ إصدار تنسيق السلك الأساسي. من المرجح أن يكون مفيدًا في الغالب للتعليمات البرمجية القديمة التي تقرأ إصدارات تنسيق السلك القديمة. قد لا يتم استدعاؤه قبل .readHeader().

deserializer.readUint32()

اقرأ عددًا صحيحًا غير موقع بحجم 32 بت وأرجعه. للاستخدام داخل deserializer._readHostObject() المخصص.

deserializer.readUint64()

اقرأ عددًا صحيحًا غير موقع بحجم 64 بت وأرجعه كمصفوفة [hi, lo] مع إدخالين لعدد صحيح غير موقع بحجم 32 بت. للاستخدام داخل deserializer._readHostObject() المخصص.

deserializer.readDouble()

اقرأ قيمة JS number. للاستخدام داخل deserializer._readHostObject() المخصص.

deserializer.readRawBytes(length)

اقرأ وحدات بايت خام من المخزن المؤقت الداخلي للمُسلسل. يجب أن تتوافق المعلمة length مع طول المخزن المؤقت الذي تم تمريره إلى serializer.writeRawBytes(). للاستخدام داخل deserializer._readHostObject() المخصص.

deserializer._readHostObject()

يتم استدعاء هذه الطريقة لقراءة نوع من كائنات المضيف، أي كائن يتم إنشاؤه بواسطة روابط C++ الأصلية. إذا لم يكن من الممكن إلغاء تسلسل البيانات، فيجب طرح استثناء مناسب.

هذه الطريقة غير موجودة في فئة Deserializer نفسها ولكن يمكن توفيرها بواسطة الفئات الفرعية.

الفئة: v8.DefaultSerializer

أُضيف في: v8.0.0

صنف فرعي من Serializer يقوم بتسلسل كائنات TypedArray (خاصةً Buffer) و DataView ككائنات مضيفة، ويقوم فقط بتخزين الجزء من ArrayBuffer الأساسي الذي تشير إليه.

الفئة: v8.DefaultDeserializer

أُضيف في: v8.0.0

صنف فرعي من Deserializer يتوافق مع التنسيق الذي يكتبه DefaultSerializer.

خطافات Promise

يمكن استخدام واجهة promiseHooks لتتبع أحداث دورة حياة الوعد. لتتبع جميع الأنشطة غير المتزامنة، راجع async_hooks الذي يستخدم هذا الوحدة داخليًا لإنتاج أحداث دورة حياة الوعد بالإضافة إلى أحداث لموارد غير متزامنة أخرى. لإدارة سياق الطلب، راجع AsyncLocalStorage.

js
import { promiseHooks } from 'node:v8';

// هناك أربعة أحداث دورة حياة تنتجها الوعود:

// يمثل حدث `init` إنشاء وعد. يمكن أن يكون هذا إنشاءً مباشرًا مثل
// مع `new Promise(...)` أو استمرارًا مثل `then()` أو `catch()`.
// يحدث أيضًا عندما يتم استدعاء دالة غير متزامنة أو تقوم بـ `await`.
// إذا تم إنشاء وعد استمرارية، فسيكون `parent` هو الوعد الذي يمثله.
function init(promise, parent) {
  console.log('تم إنشاء وعد', { promise, parent });
}

// يحدث حدث `settled` عندما يتلقى الوعد قيمة حل أو رفض.
// قد يحدث هذا بشكل متزامن مثل استخدام `Promise.resolve()` على
// إدخال غير وعد.
function settled(promise) {
  console.log('تم حل وعد أو رفضه', { promise });
}

// يتم تشغيل حدث `before` مباشرة قبل تشغيل معالج `then()` أو `catch()`
// أو استئناف تنفيذ `await`.
function before(promise) {
  console.log('وشك وعد استدعاء معالج then', { promise });
}

// يتم تشغيل حدث `after` مباشرة بعد تشغيل معالج `then()` أو عند
// يبدأ `await` بعد الاستئناف من آخر.
function after(promise) {
  console.log('انتهى الوعد من استدعاء معالج then', { promise });
}

// يمكن بدء وإيقاف خطافات دورة الحياة بشكل فردي
const stopWatchingInits = promiseHooks.onInit(init);
const stopWatchingSettleds = promiseHooks.onSettled(settled);
const stopWatchingBefores = promiseHooks.onBefore(before);
const stopWatchingAfters = promiseHooks.onAfter(after);

// أو يمكن بدؤها وإيقافها في مجموعات
const stopHookSet = promiseHooks.createHook({
  init,
  settled,
  before,
  after,
});

// لإيقاف خطاف، قم باستدعاء الدالة التي تم إرجاعها عند إنشائها.
stopWatchingInits();
stopWatchingSettleds();
stopWatchingBefores();
stopWatchingAfters();
stopHookSet();

promiseHooks.onInit(init)

أضيف في: v17.1.0, v16.14.0

يجب أن يكون خطاف init دالة بسيطة. توفير دالة غير متزامنة سيؤدي إلى رمي خطأ لأنه سينتج حلقة مهام دقيقة لانهائية.

js
import { promiseHooks } from 'node:v8';

const stop = promiseHooks.onInit((promise, parent) => {});
js
const { promiseHooks } = require('node:v8');

const stop = promiseHooks.onInit((promise, parent) => {});

promiseHooks.onSettled(settled)

أضيف في: v17.1.0, v16.14.0

يجب أن يكون خطاف settled دالة بسيطة. توفير دالة غير متزامنة سيؤدي إلى رمي خطأ لأنه سينتج حلقة مهام دقيقة لانهائية.

js
import { promiseHooks } from 'node:v8';

const stop = promiseHooks.onSettled((promise) => {});
js
const { promiseHooks } = require('node:v8');

const stop = promiseHooks.onSettled((promise) => {});

promiseHooks.onBefore(before)

أضيف في: v17.1.0, v16.14.0

يجب أن يكون خطاف before دالة بسيطة. توفير دالة غير متزامنة سيؤدي إلى رمي خطأ لأنه سينتج حلقة مهام دقيقة لانهائية.

js
import { promiseHooks } from 'node:v8';

const stop = promiseHooks.onBefore((promise) => {});
js
const { promiseHooks } = require('node:v8');

const stop = promiseHooks.onBefore((promise) => {});

promiseHooks.onAfter(after)

أُضيف في: v17.1.0, v16.14.0

يجب أن يكون خطاف after دالة عادية. توفير دالة غير متزامنة سيؤدي إلى ظهور خطأ لأنه سينتج حلقة مهام صغيرة لا نهائية.

js
import { promiseHooks } from 'node:v8';

const stop = promiseHooks.onAfter((promise) => {});
js
const { promiseHooks } = require('node:v8');

const stop = promiseHooks.onAfter((promise) => {});

promiseHooks.createHook(callbacks)

أُضيف في: v17.1.0, v16.14.0

يجب أن تكون استدعاءات الخطاف دوال عادية. توفير دوال غير متزامنة سيؤدي إلى ظهور خطأ لأنه سينتج حلقة مهام صغيرة لا نهائية.

تسجل دوالًا ليتم استدعاؤها لأحداث مختلفة خلال دورة حياة كل وعد.

يتم استدعاء الاستدعاءات init()/before()/after()/settled() للأحداث المعنية خلال دورة حياة الوعد.

جميع الاستدعاءات اختيارية. على سبيل المثال، إذا كانت هناك حاجة فقط إلى تتبع إنشاء الوعد، فستكون هناك حاجة فقط إلى تمرير استدعاء init. توجد تفاصيل جميع الدوال التي يمكن تمريرها إلى callbacks في قسم استدعاءات الخطاف.

js
import { promiseHooks } from 'node:v8';

const stopAll = promiseHooks.createHook({
  init(promise, parent) {},
});
js
const { promiseHooks } = require('node:v8');

const stopAll = promiseHooks.createHook({
  init(promise, parent) {},
});

خطاف ردود الاتصال

تم تصنيف الأحداث الرئيسية في دورة حياة الوعد إلى أربع مناطق: إنشاء الوعد، قبل/بعد استدعاء معالج الاستمرار أو حول انتظار، وعندما يتم حل الوعد أو رفضه.

في حين أن هذه الخطافات مماثلة لتلك الخاصة بـ async_hooks إلا أنها تفتقر إلى خطاف destroy. تمثل الأنواع الأخرى من الموارد غير المتزامنة عادةً المقابس أو واصفات الملفات التي لها حالة "مغلقة" مميزة للتعبير عن حدث دورة حياة destroy بينما تظل الوعود قابلة للاستخدام طالما أن التعليمات البرمجية لا تزال قادرة على الوصول إليها. يتم استخدام تتبع تجميع البيانات المهملة لجعل الوعود تتناسب مع نموذج أحداث async_hooks، ومع ذلك فإن هذا التتبع مكلف للغاية وقد لا يتم حتى تجميع البيانات المهملة الخاصة بها بالضرورة.

نظرًا لأن الوعود هي موارد غير متزامنة يتم تتبع دورة حياتها عبر آلية خطافات الوعد، يجب ألا تكون وظائف init()‎ و before()‎ و after()‎ و settled()‎ غير متزامنة لأنها تنشئ المزيد من الوعود التي من شأنها أن تنتج حلقة لا نهائية.

بينما يتم استخدام واجهة برمجة التطبيقات هذه لتغذية أحداث الوعد في async_hooks، فإن الترتيب بين الاثنين غير محدد. كلتا واجهتي برمجة التطبيقات متعددة المستأجرين وبالتالي يمكن أن تنتج أحداثًا بأي ترتيب بالنسبة لبعضهما البعض.

init(promise, parent)‎

  • promise <Promise> الوعد الذي يتم إنشاؤه.
  • parent <Promise> الوعد المستمر من، إذا كان ذلك ممكنًا.

يتم استدعاؤها عند إنشاء وعد. هذا لا يعني أن أحداث before/after المقابلة ستحدث، فقط أن الاحتمالية موجودة. سيحدث هذا إذا تم إنشاء وعد دون الحصول على استمرار أبدًا.

before(promise)‎

يتم استدعاؤها قبل تنفيذ استمرار الوعد. يمكن أن يكون هذا في شكل معالجات then()‎ أو catch()‎ أو finally()‎ أو استئناف await.

سيتم استدعاء رد اتصال before من 0 إلى N مرة. سيتم استدعاء رد اتصال before عادةً 0 مرة إذا لم يتم إجراء أي استمرار للوعد. قد يتم استدعاء رد اتصال before عدة مرات في الحالة التي تم فيها إجراء العديد من عمليات الاستمرار من نفس الوعد.

after(promise)

يتم استدعاؤها مباشرة بعد تنفيذ استمرار الوعد. قد يكون هذا بعد معالج then() أو catch() أو finally() أو قبل await بعد await آخر.

settled(promise)

يتم استدعاؤها عندما يتلقى الوعد قيمة حل أو رفض. قد يحدث هذا بشكل متزامن في حالة Promise.resolve() أو Promise.reject().

واجهة برمجة تطبيقات لقطة بدء التشغيل

تمت الإضافة في: v18.6.0, v16.17.0

[ثابت: 1 - تجريبي]

ثابت: 1 الاستقرار: 1 - تجريبي

يمكن استخدام واجهة v8.startupSnapshot لإضافة خطافات التسلسل وإلغاء التسلسل للقطات بدء التشغيل المخصصة.

bash
$ node --snapshot-blob snapshot.blob --build-snapshot entry.js
# هذا يطلق عملية مع اللقطة {#this-launches-a-process-with-the-snapshot}
$ node --snapshot-blob snapshot.blob

في المثال أعلاه، يمكن لـ entry.js استخدام طرق من واجهة v8.startupSnapshot لتحديد كيفية حفظ معلومات للكائنات المخصصة في اللقطة أثناء التسلسل وكيف يمكن استخدام المعلومات لمزامنة هذه الكائنات أثناء إلغاء تسلسل اللقطة. على سبيل المثال، إذا كان entry.js يحتوي على البرنامج النصي التالي:

js
'use strict';

const fs = require('node:fs');
const zlib = require('node:zlib');
const path = require('node:path');
const assert = require('node:assert');

const v8 = require('node:v8');

class BookShelf {
  storage = new Map();

  // قراءة سلسلة من الملفات من الدليل وتخزينها في التخزين.
  constructor(directory, books) {
    for (const book of books) {
      this.storage.set(book, fs.readFileSync(path.join(directory, book)));
    }
  }

  static compressAll(shelf) {
    for (const [ book, content ] of shelf.storage) {
      shelf.storage.set(book, zlib.gzipSync(content));
    }
  }

  static decompressAll(shelf) {
    for (const [ book, content ] of shelf.storage) {
      shelf.storage.set(book, zlib.gunzipSync(content));
    }
  }
}

// __dirname هنا هو المكان الذي يتم فيه وضع برنامج اللقطة النصي
// خلال وقت بناء اللقطة.
const shelf = new BookShelf(__dirname, [
  'book1.en_US.txt',
  'book1.es_ES.txt',
  'book2.zh_CN.txt',
]);

assert(v8.startupSnapshot.isBuildingSnapshot());
// عند تسلسل اللقطة، قم بضغط الكتب لتقليل الحجم.
v8.startupSnapshot.addSerializeCallback(BookShelf.compressAll, shelf);
// عند إلغاء تسلسل اللقطة، قم بفك ضغط الكتب.
v8.startupSnapshot.addDeserializeCallback(BookShelf.decompressAll, shelf);
v8.startupSnapshot.setDeserializeMainFunction((shelf) => {
  // يتم تحديث process.env و process.argv أثناء اللقطة
  // إلغاء التسلسل.
  const lang = process.env.BOOK_LANG || 'en_US';
  const book = process.argv[1];
  const name = `${book}.${lang}.txt`;
  console.log(shelf.storage.get(name));
}, shelf);

سيقوم الملف الثنائي الناتج بطباعة البيانات التي تم إلغاء تسلسلها من اللقطة أثناء بدء التشغيل، باستخدام process.env و process.argv المحدثين للعملية التي تم إطلاقها:

bash
$ BOOK_LANG=es_ES node --snapshot-blob snapshot.blob book1
# يطبع محتوى book1.es_ES.txt الذي تم إلغاء تسلسله من اللقطة. {#prints-content-of-book1es_estxt-deserialized-from-the-snapshot}

حاليًا، لا يمكن أخذ لقطة للتطبيق الذي تم إلغاء تسلسله من لقطة أرض المستخدم مرة أخرى، لذلك تتوفر واجهات برمجة التطبيقات هذه فقط للتطبيقات التي لم يتم إلغاء تسلسلها من لقطة أرض المستخدم.

v8.startupSnapshot.addSerializeCallback(callback[, data])

تمت إضافته في: v18.6.0, v16.17.0

  • callback <الدالة> استدعاء يتم استدعاؤه قبل التسلسل.
  • data <أي> بيانات اختيارية سيتم تمريرها إلى callback عند استدعائها.

أضف استدعاءً سيتم استدعاؤه عندما تكون نسخة Node.js على وشك التسلسل إلى لقطة والخروج. يمكن استخدام هذا لتحرير الموارد التي لا ينبغي أو لا يمكن تسلسلها أو لتحويل بيانات المستخدم إلى نموذج أكثر ملاءمة للتسلسل.

يتم تشغيل عمليات الاستدعاء بالترتيب الذي تمت إضافتها به.

v8.startupSnapshot.addDeserializeCallback(callback[, data])

تمت إضافته في: v18.6.0, v16.17.0

  • callback <الدالة> استدعاء يتم استدعاؤه بعد إلغاء تسلسل اللقطة.
  • data <أي> بيانات اختيارية سيتم تمريرها إلى callback عند استدعائها.

أضف استدعاءً سيتم استدعاؤه عند إلغاء تسلسل نسخة Node.js من لقطة. سيتم تسلسل callback و data (إذا تم توفيرها) في اللقطة، ويمكن استخدامهما لإعادة تهيئة حالة التطبيق أو لإعادة الحصول على الموارد التي يحتاجها التطبيق عند إعادة تشغيل التطبيق من اللقطة.

يتم تشغيل عمليات الاستدعاء بالترتيب الذي تمت إضافتها به.

v8.startupSnapshot.setDeserializeMainFunction(callback[, data])

تمت إضافته في: v18.6.0, v16.17.0

  • callback <الدالة> استدعاء سيتم استدعاؤه كنقطة إدخال بعد إلغاء تسلسل اللقطة.
  • data <أي> بيانات اختيارية سيتم تمريرها إلى callback عند استدعائها.

يقوم هذا بتعيين نقطة إدخال تطبيق Node.js عند إلغاء تسلسله من لقطة. يمكن استدعاء هذا مرة واحدة فقط في البرنامج النصي لإنشاء اللقطة. في حالة استدعائه، لن يحتاج التطبيق الذي تم إلغاء تسلسله بعد الآن إلى برنامج نصي إضافي لنقطة الإدخال لبدء التشغيل وسيقوم ببساطة باستدعاء الاستدعاء مع البيانات التي تم إلغاء تسلسلها (إذا تم توفيرها)، وإلا سيظل برنامج نصي لنقطة الإدخال بحاجة إلى تزويده للتطبيق الذي تم إلغاء تسلسله.

v8.startupSnapshot.isBuildingSnapshot()

تمت الإضافة في: v18.6.0, v16.17.0

يُرجع true إذا تم تشغيل مثيل Node.js لإنشاء لقطة.

الصنف: v8.GCProfiler

تمت الإضافة في: v19.6.0, v18.15.0

تجمع واجهة برمجة التطبيقات هذه بيانات GC في الخيط الحالي.

new v8.GCProfiler()

تمت الإضافة في: v19.6.0, v18.15.0

إنشاء مثيل جديد للصنف v8.GCProfiler.

profiler.start()

تمت الإضافة في: v19.6.0, v18.15.0

بدء تجميع بيانات GC.

profiler.stop()

تمت الإضافة في: v19.6.0, v18.15.0

إيقاف تجميع بيانات GC وإرجاع كائن. محتوى الكائن كما يلي.

json
{
  "version": 1,
  "startTime": 1674059033862,
  "statistics": [
    {
      "gcType": "Scavenge",
      "beforeGC": {
        "heapStatistics": {
          "totalHeapSize": 5005312,
          "totalHeapSizeExecutable": 524288,
          "totalPhysicalSize": 5226496,
          "totalAvailableSize": 4341325216,
          "totalGlobalHandlesSize": 8192,
          "usedGlobalHandlesSize": 2112,
          "usedHeapSize": 4883840,
          "heapSizeLimit": 4345298944,
          "mallocedMemory": 254128,
          "externalMemory": 225138,
          "peakMallocedMemory": 181760
        },
        "heapSpaceStatistics": [
          {
            "spaceName": "read_only_space",
            "spaceSize": 0,
            "spaceUsedSize": 0,
            "spaceAvailableSize": 0,
            "physicalSpaceSize": 0
          }
        ]
      },
      "cost": 1574.14,
      "afterGC": {
        "heapStatistics": {
          "totalHeapSize": 6053888,
          "totalHeapSizeExecutable": 524288,
          "totalPhysicalSize": 5500928,
          "totalAvailableSize": 4341101384,
          "totalGlobalHandlesSize": 8192,
          "usedGlobalHandlesSize": 2112,
          "usedHeapSize": 4059096,
          "heapSizeLimit": 4345298944,
          "mallocedMemory": 254128,
          "externalMemory": 225138,
          "peakMallocedMemory": 181760
        },
        "heapSpaceStatistics": [
          {
            "spaceName": "read_only_space",
            "spaceSize": 0,
            "spaceUsedSize": 0,
            "spaceAvailableSize": 0,
            "physicalSpaceSize": 0
          }
        ]
      }
    }
  ],
  "endTime": 1674059036865
}

فيما يلي مثال.

js
const { GCProfiler } = require('node:v8');
const profiler = new GCProfiler();
profiler.start();
setTimeout(() => {
  console.log(profiler.stop());
}, 1000);