V8
Source Code: lib/v8.js
يعرض الوحدة النمطية node:v8
واجهات برمجة تطبيقات خاصة بإصدار V8 المُدمج في ملف Node.js الثنائي. ويمكن الوصول إليه باستخدام:
const v8 = require('node:v8')
v8.cachedDataVersionTag()
مضاف في: v8.0.0
- المُخرجات: <integer>
يُعيد عددًا صحيحًا يمثل علامة إصدار مُشتقة من إصدار V8، وأعلام سطر الأوامر، وميزات وحدة المعالجة المركزية المُكتشفة. وهذا مفيد لتحديد ما إذا كان المخزن المؤقت cachedData
لـ vm.Script
متوافقًا مع مثيل 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
. يُعيد كائنًا يحتوي على الخصائص التالية:
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])
[History]
الإصدار | التغييرات |
---|---|
v19.1.0 | دعم خيارات تكوين لقطة كومة الذاكرة. |
v11.13.0 | تمت الإضافة في: v11.13.0 |
options
<Object>المُرجَع: <stream.Readable> تيار قابل للقراءة يحتوي على لقطة كومة V8.
يقوم بإنشاء لقطة من كومة V8 الحالية، ويرجع تيارًا قابلًا للقراءة يمكن استخدامه لقراءة التمثيل المتسلسل JSON. يهدف تنسيق تيار JSON هذا إلى استخدامه مع أدوات مثل Chrome DevTools. مخطط JSON غير موثق ومحدد بمحرك V8. لذلك، قد يتغير المخطط من إصدار V8 إلى التالي.
يتطلب إنشاء لقطة كومة ذاكرة بحجم ضعف حجم الكومة في وقت إنشاء اللقطة. وهذا يؤدي إلى خطر إنهاء العملية بواسطة قاتلات OOM.
إنشاء لقطة هو عملية متزامنة تسد حلقة الحدث لفترة زمنية تعتمد على حجم الكومة.
// طباعة لقطة كومة الذاكرة على وحدة التحكم
const v8 = require('node:v8')
const stream = v8.getHeapSnapshot()
stream.pipe(process.stdout)
v8.getHeapSpaceStatistics()
[History]
الإصدار | التغييرات |
---|---|
v7.5.0 | دعم القيم التي تتجاوز نطاق عدد صحيح بدون إشارة 32 بت. |
v6.0.0 | تمت الإضافة في: v6.0.0 |
- المُرجَع: <Object[]>
يرجع إحصائيات حول مسافات كومة V8، أي الأجزاء التي تشكل كومة V8. لا يمكن ضمان ترتيب مسافات الكومة، ولا توافر مساحة كومة، نظرًا لأن الإحصائيات يتم توفيرها عبر دالة V8 GetHeapSpaceStatistics
وقد تتغير من إصدار V8 إلى التالي.
القيمة المُرجعة هي مصفوفة من الكائنات التي تحتوي على الخصائص التالية:
space_name
<string>space_size
<number>space_used_size
<number>space_available_size
<number>physical_space_size
<number>
[
{
"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])
مضاف في: v22.0.0، v20.13.0
[مستقر: 1 - تجريبي]
مستقر: 1 استقرار: 1.1 - تطوير نشط
ctor
<Function> مُنشئ يمكن استخدامه للبحث في سلسلة النموذج الأولي من أجل تصفية الكائنات الهدف في الذاكرة.options
<undefined> | <Object>format
<string> إذا كان'count'
، يتم إرجاع عدد الكائنات المتطابقة. إذا كان'summary'
، يتم إرجاع مصفوفة تحتوي على سلاسل مُلخص للكائنات المتطابقة.
مُخرجات: {number|Array
يشبه هذا واجهة برمجة التطبيقات [
queryObjects()`](https://developer.chrome.com/docs/devtools/console/utilities#queryObjects-function) لوحدة تحكم Chrome DevTools. يمكن استخدامه للبحث عن الكائنات التي تحتوي على المُنشئ المطابق في سلسلة النموذج الأولي في الذاكرة بعد عملية جمع القمامة الكاملة، والتي يمكن أن تكون مفيدة لاختبارات انحدار تسرب الذاكرة. لتجنب النتائج المُفاجئة، يجب على المستخدمين تجنب استخدام واجهة برمجة التطبيقات هذه على المُنشئات التي لا يتحكمون في تنفيذها، أو على المُنشئات التي يمكن استدعائها من قبل أطراف أخرى في التطبيق.
لتجنب التسريبات العرضية، لا تُعيد واجهة برمجة التطبيقات هذه مراجع خام للكائنات الموجودة. بشكل افتراضي، تُعيد عدد الكائنات الموجودة. إذا كانت options.format
هي 'summary'
، فإنها تُعيد مصفوفة تحتوي على تمثيلات سلسلة مُوجزة لكل كائن. تشبه الرؤية المُقدمة في واجهة برمجة التطبيقات هذه ما تقدمه لقطة الذاكرة، بينما يمكن للمستخدمين توفير تكلفة التسلسل والتحليل وإجراء تصفية مباشرة للكائنات الهدف أثناء البحث.
لا يتم تضمين الكائنات المُنشأة فقط في سياق التنفيذ الحالي في النتائج.
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' }))
// لاحظ أنه عندما تكون هناك فئات فرعية ترث من مُنشئ،
// يظهر المُنشئ أيضًا في سلسلة النموذج الأولي للنموذج الأولي للفئات الفرعية، لذلك سيتم تضمين النموذج الأولي للفئات الفرعية أيضًا في النتيجة.
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' }))
// لاحظ أنه عندما تكون هناك فئات فرعية ترث من مُنشئ،
// يظهر المُنشئ أيضًا في سلسلة النموذج الأولي للنموذج الأولي للفئات الفرعية، لذلك سيتم تضمين النموذج الأولي للفئات الفرعية أيضًا في النتيجة.
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}`)
// الآن الحصول على heapdump للمؤشر الترابط الرئيسي.
console.log(`main thread heapdump: ${writeHeapSnapshot()}`)
})
// أخبر العامل بإنشاء heapdump.
worker.postMessage('heapdump')
} else {
parentPort.once('message', message => {
if (message === 'heapdump') {
// توليد heapdump للعامل
// وإرجاع اسم الملف إلى الأصل.
parentPort.postMessage(writeHeapSnapshot())
}
})
}
v8.setHeapSnapshotNearHeapLimit(limit)
تم الإضافة في: v18.10.0، v16.18.0
limit
<عدد صحيح>
واجهة برمجة التطبيقات هي عملية لا تعمل إذا تم تعيين --heapsnapshot-near-heap-limit
بالفعل من سطر الأوامر أو تم استدعاء واجهة برمجة التطبيقات أكثر من مرة. يجب أن يكون limit
عددًا صحيحًا موجبًا. راجع --heapsnapshot-near-heap-limit
لمزيد من المعلومات.
واجهة برمجة تسلسل البيانات
توفر واجهة برمجة تسلسل البيانات وسائل لتسلسل قيم 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
<أي>
يُسلسل قيمة JavaScript ويضيف التمثيل المُسلسل إلى المخزن المؤقت الداخلي.
يُلقي هذا خطأ إذا تعذر تسلسل value
.
serializer.releaseBuffer()
- مُخرجات: <Buffer>
يُعيد المخزن المؤقت الداخلي المُخزّن. لا يجب استخدام هذا المُسلسل بمجرد إطلاق المخزن المؤقت. يؤدي استدعاء هذه الطريقة إلى سلوك غير مُعرّف إذا فشل الكتابة السابقة.
serializer.transferArrayBuffer(id, arrayBuffer)
id
<عدد صحيح> عدد صحيح بدون إشارة 32 بت.arrayBuffer
<ArrayBuffer> مثيلArrayBuffer
.
يُشير إلى أن ArrayBuffer
لديه محتوياته المُنقلّة خارج النطاق. مرّر ArrayBuffer
المُقابِل في سياق إلغاء التسلسل إلى deserializer.transferArrayBuffer()
.
serializer.writeUint32(value)
value
<عدد صحيح>
اكتب عددًا صحيحًا بدون إشارة 32 بت. للاستخدام داخل مُخصص serializer._writeHostObject()
.
serializer.writeUint64(hi, lo)
hi
<عدد صحيح>lo
<عدد صحيح>
اكتب عددًا صحيحًا بدون إشارة 64 بت، مُقسّمًا إلى أجزاء عالية ومنخفضة 32 بت. للاستخدام داخل مُخصص serializer._writeHostObject()
.
serializer.writeDouble(value)
value
<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
s).
deserializer.getWireFormatVersion()
- قيمة مُعادة: <integer>
يقوم بقراءة إصدار تنسيق السلك الأساسي. من المحتمل أن يكون مفيدًا في الغالب للكود القديم الذي يقرأ إصدارات تنسيق سلك قديمة. قد لا يتم استدعاء هذه الدالة قبل .readHeader()
.
deserializer.readUint32()
- قيمة مُعادة: <integer>
يقوم بقراءة عدد صحيح بدون إشارة 32 بت خام وإعادته. للاستخدام داخل مُخصص deserializer._readHostObject()
.
deserializer.readUint64()
- قيمة مُعادة: <integer[]>
يقوم بقراءة عدد صحيح بدون إشارة 64 بت خام وإعادته كمصفوفة [hi, lo]
مع مُدخلين صحيحين بدون إشارة 32 بت. للاستخدام داخل مُخصص deserializer._readHostObject()
.
deserializer.readDouble()
- قيمة مُعادة: <number>
يقوم بقراءة قيمة number
من JS. للاستخدام داخل مُخصص deserializer._readHostObject()
.
deserializer.readRawBytes(length)
يقوم بقراءة البايت الخام من المخزن المؤقت الداخلي لـ deserializer. يجب أن يتوافق مُعامل 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
.
خطافات الوعود
يمكن استخدام واجهة 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
<Function> دالة الاستدعاءinit
التي تُستدعى عند إنشاء وعد.- الإرجاع: <Function> استدعاء لإيقاف الخطاف.
يجب أن تكون دالة الخطاف 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
<Function> دالة الاستدعاءsettled
التي تُستدعى عند حل أو رفض وعد.- الإرجاع: <Function> استدعاء لإيقاف الخطاف.
يجب أن تكون دالة الخطاف 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
<Function> دالة الاستدعاءbefore
التي تُستدعى قبل تنفيذ استمرار وعد.- الإرجاع: <Function> استدعاء لإيقاف الخطاف.
يجب أن تكون دالة الخطاف 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
<Function> دالة الاستدعاءafter
التي سيتم استدعاؤها بعد تنفيذ استمرار الوعد.- الإرجاع: <Function> دعوة لإيقاف الخطاف.
يجب أن تكون دالة الخطاف 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
<Object> استدعاءات الخطاف لتسجيلهاinit
<Function> دالة الاستدعاءinit
.before
<Function> دالة الاستدعاءbefore
.after
<Function> دالة الاستدعاءafter
.settled
<Function> دالة الاستدعاءsettled
.
الإرجاع: <Function> يستخدم لتعطيل الخطافات
يجب أن تكون استدعاءات دالة الخطاف دالات عادية. إنشاء دوال غير متزامنة سيرمي خطأ لأنه سيؤدي إلى حلقة مايكروتاسك لانهائية.
تسجل الدوال التي سيتم استدعاؤها لأحداث عمر مختلفة لكل وعد.
يتم استدعاء استدعاءات الدوال 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)
promise
<Promise> الوعد الذي يتم إنشاؤه.parent
<Promise> الوعد الذي تم الاستمرار منه، إذا كان ذلك ينطبق.
يتم استدعاء هذه الوظيفة عند إنشاء وعد. هذا لا يعني أن أحداث before
/after
المقابلة ستحدث، بل فقط أن الاحتمال موجود. سيحدث هذا إذا تم إنشاء وعد دون الحصول على استمرار على الإطلاق.
before(promise)
promise
<Promise>
يتم استدعاء هذه الوظيفة قبل تنفيذ استمرار الوعد. يمكن أن يكون هذا في شكل مُعالِجات then()
أو catch()
أو finally()
أو استئناف await
.
سيتم استدعاء مُعالِج before
من 0 إلى N مرة. سيتم عادةً استدعاء مُعالِج before
0 مرة إذا لم يتم إجراء أي استمرار للوعد على الإطلاق. قد يتم استدعاء مُعالِج before
عدة مرات في حالة إجراء العديد من الاستمرارات من نفس الوعد.
after(promise)
promise
<Promise>
يطلق مباشرة بعد تنفيذ استمرار الوعد. قد يكون هذا بعد مُعالِج then()
أو catch()
أو finally()
أو قبل await
بعد await
آخر.
settled(promise)
promise
<Promise>
يطلق عندما يتلقى الوعد قيمة حل أو رفض. قد يحدث هذا بشكل متزامن في حالة Promise.resolve()
أو Promise.reject()
.
واجهة برمجة تطبيقات لقطة بدء التشغيل
مضاف في: v18.6.0، v16.17.0
يمكن استخدام واجهة 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
<Function> دالة مُستدعاة قبل التسلسل.data
<any> بيانات اختيارية سيتم تمريرها إلىcallback
عند استدعائها.
إضافة دالة مُستدعاة سيتم استدعاؤها عندما تكون مثيل Node.js على وشك أن يتم تسلسله إلى لقطة والخروج. يمكن استخدام هذا لإطلاق الموارد التي لا ينبغي أو لا يمكن تسلسلها أو لتحويل بيانات المستخدم إلى شكل أكثر ملاءمة للتسلسل.
يتم تشغيل الدوال المُستدعاة بالترتيب الذي تمت إضافتها به.
v8.startupSnapshot.addDeserializeCallback(callback[, data])
تم الإضافة في: v18.6.0، v16.17.0
callback
<Function> دالة مُستدعاة بعد فك تسلسل اللقطة.data
<any> بيانات اختيارية سيتم تمريرها إلىcallback
عند استدعائها.
إضافة دالة مُستدعاة سيتم استدعاؤها عندما يتم فك تسلسل مثيل Node.js من لقطة. سيتم تسلسل callback
و data
(إذا تم توفيره) إلى اللقطة، ويمكن استخدامهما لإعادة تهيئة حالة التطبيق أو لإعادة الحصول على الموارد التي يحتاجها التطبيق عند إعادة تشغيل التطبيق من اللقطة.
يتم تشغيل الدوال المُستدعاة بالترتيب الذي تمت إضافتها به.
v8.startupSnapshot.setDeserializeMainFunction(callback[, data])
تم الإضافة في: v18.6.0، v16.17.0
callback
<Function> دالة مُستدعاة كنقطة دخول بعد فك تسلسل اللقطة.data
<any> بيانات اختيارية سيتم تمريرها إلىcallback
عند استدعائها.
هذا يحدد نقطة دخول تطبيق Node.js عندما يتم فك تسلسله من لقطة. يمكن استدعاء هذا مرة واحدة فقط في برنامج إنشاء اللقطة. إذا تم استدعاؤه، فلن يحتاج التطبيق المُفكك تسلسله إلى برنامج نقطة دخول إضافي للبدء وسوف يقوم ببساطة باستدعاء الدالة المُستدعاة بالإضافة إلى البيانات المُفككة تسلسله (إذا تم توفيرها)، وإلا فلا يزال يتعين توفير برنامج نقطة دخول للتطبيق المُفكك تسلسله.
v8.startupSnapshot.isBuildingSnapshot()
أضيف في: v18.6.0، v16.17.0
- الإرجاع: <boolean>
ترجع true
إذا تم تشغيل مثيل Node.js لإنشاء لقطة.
الصنف: v8.GCProfiler
أضيف في: v19.6.0، v18.15.0
يُجمع هذا الـ API بيانات 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)