افهم كيف يعمل جامع القمامة، استخدم المراجع الضعيفة لتجنب التسريبات، وخفف من العمل المكلف باستخدام debounce وthrottle.
افتح هذا الدرس في Kodokonيعتمد جامع القمامة في V8 على إمكانية الوصول (reachability): يصبح الكائن قابلا للجمع حالما لا تربطه أي سلسلة مراجع بالجذور (المكدس، النطاقات النشطة، المتغيرات العامة). جامع القمامة جيلي: تعيش الكائنات الحديثة في *الحضانة*، تجمع كثيرا وبسرعة (scavenge)؛ ويرقى الناجون إلى الجيل القديم، الذي يعالج بمسح-وكنس تزايدي. لا تأتي التسريبات الكلاسيكية من جامع القمامة بل من مراجع نسيتها: ذاكرات مؤقتة قائمة على Map، مستمعون لا يفصلون أبدا، مغلفات تلتقط كائنات كبيرة.
const strongCache = new Map();
const weakCache = new WeakMap();
let session = { user: "ada" };
strongCache.set(session, "data");
weakCache.set(session, "data");
session = null;
// Map: the key retains the object -> memory leak
// WeakMap: the entry becomes collectableلا يحتفظ WeakMap بمفاتيحه: عندما يصبح مفتاح غير قابل للوصول من أي مكان آخر، يختفي المدخل بأكمله. النتائج التصميمية: يجب أن تكون المفاتيح كائنات (أو رموزا غير مسجلة)، والبنية ليست قابلة للتكرار ولا للقياس - كشف حجمها سيكشف سلوك جامع القمامة، وهو غير حتمي. يذهب WeakRef أبعد: يعطيك مرجعا ضعيفا مباشرا، يفك بـ deref().
let config = { theme: "dark" };
const ref = new WeakRef(config);
function readTheme() {
const target = ref.deref();
return target ? target.theme : "default";
}
console.log(readTheme()); // "dark"
config = null;
// After a GC pass, deref() may
// return undefined: plan a fallback.من جهة الأداء المدرك، يمكن أن تطلق الأحداث عالية التردد (scroll، resize، input، mousemove) مئات الاستدعاءات في الثانية. استراتيجيتان متكاملتان: debounce لا تشغل الدالة إلا بعد فترة هدوء (مثالي للبحث أثناء الكتابة)، بينما throttle تضمن تنفيذا واحدا على الأكثر لكل فترة (مثالي لتتبع التمرير).
function debounce(fn, delay) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(
() => fn.apply(this, args),
delay
);
};
}function throttle(fn, interval) {
let last = 0;
return function (...args) {
const now = Date.now();
if (now - last >= interval) {
last = now;
fn.apply(this, args);
}
};
}ref.deref() على WeakRef؟undefined إن جمعnull إن جمع الكائن