V8
كود المصدر: lib/v8.js
الوحدة node:v8
تكشف عن واجهات برمجة تطبيقات خاصة بإصدار V8 المضمن في الثنائي Node.js. يمكن الوصول إليها باستخدام:
const v8 = require('node:v8');
v8.cachedDataVersionTag()
تمت إضافتها في: v8.0.0
- الإرجاع: <integer>
إرجاع عدد صحيح يمثل علامة إصدار مشتقة من إصدار V8، وعلامات سطر الأوامر، وميزات وحدة المعالجة المركزية المكتشفة. هذا مفيد لتحديد ما إذا كانت vm.Script
cachedData
buffer متوافقة مع هذه النسخة من V8.
console.log(v8.cachedDataVersionTag()); // 3947234607
// القيمة التي يتم إرجاعها بواسطة v8.cachedDataVersionTag() مشتقة من V8
// الإصدار وعلامات سطر الأوامر وميزات وحدة المعالجة المركزية المكتشفة. اختبر أن القيمة
// يتم تحديثها بالفعل عند تبديل العلامات.
v8.setFlagsFromString('--allow_natives_syntax');
console.log(v8.cachedDataVersionTag()); // 183726201
v8.getHeapCodeStatistics()
تمت إضافتها في: v12.8.0
- الإرجاع: <Object>
احصل على إحصائيات حول الكود والبيانات الوصفية الخاصة به في الكومة، راجع V8 GetHeapCodeAndMetadataStatistics
API. تُرجع كائنًا بالخصائص التالية:
code_and_metadata_size
<number>bytecode_and_metadata_size
<number>external_script_source_size
<number>cpu_profiler_metadata_size
<number>
{
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
<الكائن>إرجاع: <stream.Readable> Readable يحتوي على لقطة الذاكرة المؤقتة V8.
يقوم بإنشاء لقطة من ذاكرة V8 المؤقتة الحالية وإرجاع Readable Stream يمكن استخدامه لقراءة التمثيل التسلسلي JSON. تم تصميم تنسيق دفق JSON هذا لاستخدامه مع أدوات مثل Chrome DevTools. مخطط JSON غير موثق وخاص بمحرك V8. لذلك، قد يتغير المخطط من إصدار V8 إلى آخر.
يتطلب إنشاء لقطة ذاكرة مؤقتة ذاكرة تبلغ حوالي ضعف حجم الذاكرة المؤقتة في وقت إنشاء اللقطة. هذا يؤدي إلى خطر إنهاء عمليات OOM للعملية.
يعد إنشاء لقطة عملية متزامنة تحظر حلقة الأحداث لفترة تعتمد على حجم الذاكرة المؤقتة.
// طباعة لقطة الذاكرة المؤقتة إلى وحدة التحكم
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 |
- إرجاع: <Object[]>
إرجاع إحصائيات حول مساحات ذاكرة V8 المؤقتة، أي المقاطع التي تشكل ذاكرة V8 المؤقتة. لا يمكن ضمان ترتيب مساحات الذاكرة المؤقتة ولا توفر مساحة ذاكرة مؤقتة حيث يتم توفير الإحصائيات عبر وظيفة V8 GetHeapSpaceStatistics
وقد تتغير من إصدار V8 إلى آخر.
القيمة التي يتم إرجاعها عبارة عن مجموعة من الكائنات التي تحتوي على الخصائص التالية:
space_name
<سلسلة>space_size
<رقم>space_used_size
<رقم>space_available_size
<رقم>physical_space_size
<رقم>
[
{
"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 |
- الإرجاع: <Object>
يُرجع كائنًا بالخصائص التالية:
total_heap_size
<number>total_heap_size_executable
<number>total_physical_size
<number>total_available_size
<number>used_heap_size
<number>heap_size_limit
<number>malloced_memory
<number>peak_malloced_memory
<number>does_zap_garbage
<number>number_of_native_contexts
<number>number_of_detached_contexts
<number>total_global_handles_size
<number>used_global_handles_size
<number>external_memory
<number>
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
هي حجم ذاكرة مخازن المصفوفات والسلاسل الخارجية.
{
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)، بينما يمكن للمستخدمين توفير تكلفة التسلسل والتحليل وتصفية الكائنات المستهدفة مباشرة أثناء البحث.
يتم تضمين الكائنات التي تم إنشاؤها في سياق التنفيذ الحالي فقط في النتائج.
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' }));
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
flags
<string>
يمكن استخدام طريقة v8.setFlagsFromString()
لتعيين علامات سطر الأوامر V8 برمجيًا. يجب استخدام هذه الطريقة بحذر. قد يؤدي تغيير الإعدادات بعد بدء تشغيل الجهاز الظاهري إلى سلوك غير متوقع، بما في ذلك الأعطال وفقدان البيانات؛ أو قد لا تفعل شيئًا ببساطة.
يمكن تحديد خيارات V8 المتاحة لإصدار من Node.js عن طريق تشغيل node --v8-options
.
الاستخدام:
// طباعة أحداث 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>إرجاع: <string> اسم الملف حيث تم حفظ اللقطة.
ينشئ لقطة من الذاكرة المؤقتة V8 الحالية ويكتبها في ملف JSON. الغرض من هذا الملف هو استخدامه مع أدوات مثل Chrome DevTools. مخطط JSON غير موثق ومحدد لمحرك V8، وقد يتغير من إصدار V8 إلى آخر.
تعتبر لقطة الذاكرة المؤقتة خاصة بمعزل V8 واحد. عند استخدام مؤشرات ترابط العامل، لن تحتوي لقطة الذاكرة المؤقتة التي تم إنشاؤها من المؤشر الرئيسي على أي معلومات حول العمال، والعكس صحيح.
يتطلب إنشاء لقطة ذاكرة مؤقتة ذاكرة بحجم ضعف حجم الذاكرة المؤقتة تقريبًا في وقت إنشاء اللقطة. هذا يؤدي إلى خطر إنهاء قتلة OOM للعملية.
يعد إنشاء لقطة عملية متزامنة تحظر حلقة الأحداث لفترة تعتمد على حجم الذاكرة المؤقتة.
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 - تجريبي
limit
<عدد صحيح>
تعتبر واجهة برمجة التطبيقات (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
buffer
<Buffer> | <TypedArray> | <DataView> مخزن مؤقت تم إرجاعه بواسطةserialize()
.
يستخدم DefaultDeserializer
مع الخيارات الافتراضية لقراءة قيمة JS من المخزن المؤقت.
الفئة: v8.Serializer
تمت إضافتها في: v8.0.0
new Serializer()
يقوم بإنشاء كائن Serializer
جديد.
serializer.writeHeader()
يكتب رأسًا، يتضمن إصدار تنسيق التسلسل.
serializer.writeValue(value)
value
<any>
يقوم بتسلسل قيمة JavaScript ويضيف التمثيل المتسلسل إلى المخزن المؤقت الداخلي.
يطرح هذا خطأ إذا تعذر تسلسل value
.
serializer.releaseBuffer()
- الإرجاع: <Buffer>
إرجاع المخزن المؤقت الداخلي المخزن. يجب عدم استخدام هذا المسلسل بمجرد تحرير المخزن المؤقت. تؤدي استدعاء هذه الطريقة إلى سلوك غير محدد إذا فشلت كتابة سابقة.
serializer.transferArrayBuffer(id, arrayBuffer)
id
<integer> عدد صحيح غير موقع 32 بت.arrayBuffer
<ArrayBuffer> مثيلArrayBuffer
.
يميز ArrayBuffer
على أنه تم نقل محتوياته خارج النطاق. قم بتمرير ArrayBuffer
المطابق في سياق إلغاء التسلسل إلى deserializer.transferArrayBuffer()
.
serializer.writeUint32(value)
value
<integer>
اكتب عددًا صحيحًا غير موقع 32 بت خامًا. للاستخدام داخل serializer._writeHostObject()
مخصص.
serializer.writeUint64(hi, lo)
اكتب عددًا صحيحًا غير موقع 64 بت خامًا، مقسمًا إلى أجزاء عالية ومنخفضة 32 بت. للاستخدام داخل serializer._writeHostObject()
مخصص.
serializer.writeDouble(value)
value
<number>
اكتب قيمة number
لـ JS. للاستخدام داخل serializer._writeHostObject()
مخصصة.
serializer.writeRawBytes(buffer)
buffer
<Buffer> | <TypedArray> | <DataView>
اكتب بايتات خام في المخزن المؤقت الداخلي للمسلسل. سيتطلب إلغاء التسلسل طريقة لحساب طول المخزن المؤقت. للاستخدام داخل serializer._writeHostObject()
مخصصة.
serializer._writeHostObject(object)
object
<Object>
يتم استدعاء هذه الطريقة لكتابة نوع من كائن المضيف، أي كائن تم إنشاؤه بواسطة روابط C ++ الأصلية. إذا لم يكن من الممكن تسلسل object
، فيجب طرح استثناء مناسب.
هذه الطريقة غير موجودة في فئة Serializer
نفسها ولكن يمكن توفيرها بواسطة الفئات الفرعية.
serializer._getDataCloneError(message)
message
<string>
يتم استدعاء هذه الطريقة لإنشاء كائنات خطأ سيتم طرحها عندما لا يمكن استنساخ كائن.
تستخدم هذه الطريقة بشكل افتراضي مُنشئ Error
ويمكن تجاوزها في الفئات الفرعية.
serializer._getSharedArrayBufferId(sharedArrayBuffer)
sharedArrayBuffer
<SharedArrayBuffer>
يتم استدعاء هذه الطريقة عندما يكون المسلسل على وشك تسلسل كائن SharedArrayBuffer
. يجب أن تُرجع معرّف عدد صحيح غير موقع 32 بت للكائن، باستخدام نفس المعرّف إذا تم بالفعل تسلسل SharedArrayBuffer
هذا. عند إلغاء التسلسل، سيتم تمرير هذا المعرّف إلى deserializer.transferArrayBuffer()
.
إذا تعذر تسلسل الكائن، فيجب طرح استثناء.
هذه الطريقة غير موجودة في فئة Serializer
نفسها ولكن يمكن توفيرها بواسطة الفئات الفرعية.
serializer._setTreatArrayBufferViewsAsHostObjects(flag)
flag
<boolean> افتراضي:false
يشير إلى ما إذا كان سيتم التعامل مع كائنات TypedArray
و DataView
ككائنات مضيفة، أي تمريرها إلى serializer._writeHostObject()
.
الصنف: v8.Deserializer
أُضيف في: v8.0.0
new Deserializer(buffer)
buffer
<Buffer> | <TypedArray> | <DataView> مخزن مؤقت تم إرجاعه بواسطةserializer.releaseBuffer()
.
ينشئ كائن Deserializer
جديدًا.
deserializer.readHeader()
يقرأ ويتحقق من صحة رأس (بما في ذلك إصدار التنسيق). قد يرفض، على سبيل المثال، تنسيقًا سلكيًا غير صالح أو غير مدعوم. في هذه الحالة، يتم طرح Error
.
deserializer.readValue()
يزيل تسلسل قيمة JavaScript من المخزن المؤقت ويعيدها.
deserializer.transferArrayBuffer(id, arrayBuffer)
id
<integer> عدد صحيح غير موقع ذو 32 بت.arrayBuffer
<ArrayBuffer> | <SharedArrayBuffer> نسخة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
<عدد صحيح>- الإرجاع: <Buffer>
اقرأ وحدات بايت خام من المخزن المؤقت الداخلي للمُسلسل. يجب أن تتوافق المعلمة 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
.
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
<الدالة> استدعاءinit
callback المراد استدعاؤه عند إنشاء وعد.- الإرجاع: <الدالة> استدعاء لإيقاف الخطاف.
يجب أن يكون خطاف init
دالة بسيطة. توفير دالة غير متزامنة سيؤدي إلى رمي خطأ لأنه سينتج حلقة مهام دقيقة لانهائية.
import { promiseHooks } from 'node:v8';
const stop = promiseHooks.onInit((promise, parent) => {});
const { promiseHooks } = require('node:v8');
const stop = promiseHooks.onInit((promise, parent) => {});
promiseHooks.onSettled(settled)
أضيف في: v17.1.0, v16.14.0
settled
<الدالة> استدعاءsettled
callback المراد استدعاؤه عند حل الوعد أو رفضه.- الإرجاع: <الدالة> استدعاء لإيقاف الخطاف.
يجب أن يكون خطاف settled
دالة بسيطة. توفير دالة غير متزامنة سيؤدي إلى رمي خطأ لأنه سينتج حلقة مهام دقيقة لانهائية.
import { promiseHooks } from 'node:v8';
const stop = promiseHooks.onSettled((promise) => {});
const { promiseHooks } = require('node:v8');
const stop = promiseHooks.onSettled((promise) => {});
promiseHooks.onBefore(before)
أضيف في: v17.1.0, v16.14.0
before
<الدالة> استدعاءbefore
callback المراد استدعاؤه قبل تنفيذ استمرارية الوعد.- الإرجاع: <الدالة> استدعاء لإيقاف الخطاف.
يجب أن يكون خطاف before
دالة بسيطة. توفير دالة غير متزامنة سيؤدي إلى رمي خطأ لأنه سينتج حلقة مهام دقيقة لانهائية.
import { promiseHooks } from 'node:v8';
const stop = promiseHooks.onBefore((promise) => {});
const { promiseHooks } = require('node:v8');
const stop = promiseHooks.onBefore((promise) => {});
promiseHooks.onAfter(after)
أُضيف في: v17.1.0, v16.14.0
after
<دالة>after
الاستدعاء الذي سيتم استدعاؤه بعد تنفيذ استمرار الوعد.- الإرجاع: <دالة> استدعاء لإيقاف الخطاف.
يجب أن يكون خطاف after
دالة عادية. توفير دالة غير متزامنة سيؤدي إلى ظهور خطأ لأنه سينتج حلقة مهام صغيرة لا نهائية.
import { promiseHooks } from 'node:v8';
const stop = promiseHooks.onAfter((promise) => {});
const { promiseHooks } = require('node:v8');
const stop = promiseHooks.onAfter((promise) => {});
promiseHooks.createHook(callbacks)
أُضيف في: v17.1.0, v16.14.0
callbacks
<كائن> استدعاءات الخطاف المراد تسجيلهاinit
<دالة>init
الاستدعاء.before
<دالة>before
الاستدعاء.after
<دالة>after
الاستدعاء.settled
<دالة>settled
الاستدعاء.
الإرجاع: <دالة> تستخدم لتعطيل الخطافات
يجب أن تكون استدعاءات الخطاف دوال عادية. توفير دوال غير متزامنة سيؤدي إلى ظهور خطأ لأنه سينتج حلقة مهام صغيرة لا نهائية.
تسجل دوالًا ليتم استدعاؤها لأحداث مختلفة خلال دورة حياة كل وعد.
يتم استدعاء الاستدعاءات init()
/before()
/after()
/settled()
للأحداث المعنية خلال دورة حياة الوعد.
جميع الاستدعاءات اختيارية. على سبيل المثال، إذا كانت هناك حاجة فقط إلى تتبع إنشاء الوعد، فستكون هناك حاجة فقط إلى تمرير استدعاء init
. توجد تفاصيل جميع الدوال التي يمكن تمريرها إلى callbacks
في قسم استدعاءات الخطاف.
import { promiseHooks } from 'node:v8';
const stopAll = promiseHooks.createHook({
init(promise, parent) {},
});
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)
يتم استدعاؤها عند إنشاء وعد. هذا لا يعني أن أحداث before
/after
المقابلة ستحدث، فقط أن الاحتمالية موجودة. سيحدث هذا إذا تم إنشاء وعد دون الحصول على استمرار أبدًا.
before(promise)
promise
<Promise>
يتم استدعاؤها قبل تنفيذ استمرار الوعد. يمكن أن يكون هذا في شكل معالجات then()
أو catch()
أو finally()
أو استئناف await
.
سيتم استدعاء رد اتصال before
من 0 إلى N مرة. سيتم استدعاء رد اتصال before
عادةً 0 مرة إذا لم يتم إجراء أي استمرار للوعد. قد يتم استدعاء رد اتصال before
عدة مرات في الحالة التي تم فيها إجراء العديد من عمليات الاستمرار من نفس الوعد.
after(promise)
promise
<وعد>
يتم استدعاؤها مباشرة بعد تنفيذ استمرار الوعد. قد يكون هذا بعد معالج then()
أو catch()
أو finally()
أو قبل await
بعد await
آخر.
settled(promise)
promise
<وعد>
يتم استدعاؤها عندما يتلقى الوعد قيمة حل أو رفض. قد يحدث هذا بشكل متزامن في حالة Promise.resolve()
أو Promise.reject()
.
واجهة برمجة تطبيقات لقطة بدء التشغيل
تمت الإضافة في: v18.6.0, v16.17.0
[ثابت: 1 - تجريبي]
ثابت: 1 الاستقرار: 1 - تجريبي
يمكن استخدام واجهة v8.startupSnapshot
لإضافة خطافات التسلسل وإلغاء التسلسل للقطات بدء التشغيل المخصصة.
$ 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
يحتوي على البرنامج النصي التالي:
'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
المحدثين للعملية التي تم إطلاقها:
$ 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
- الإرجاع: <boolean>
يُرجع 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 وإرجاع كائن. محتوى الكائن كما يلي.
{
"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
}
فيما يلي مثال.
const { GCProfiler } = require('node:v8');
const profiler = new GCProfiler();
profiler.start();
setTimeout(() => {
console.log(profiler.stop());
}, 1000);