برنامه نویسی

Node.js وقفه های زمانی و نشت حافظه

معرفی

  • بررسی اجمالی موضوع: روشی که Node.js با وقفه های زمانی مدیریت می کند می تواند منجر به نشت حافظه قابل توجهی شود.
  • زمینه: setTimeout API معمولا در هر دو مرورگر و Node.js استفاده می شود. در حالی که به طور مشابه کار می کند، Node.js یک شی پیچیده تر را برمی گرداند، که می تواند مشکلاتی ایجاد کند.

میانای برنامه‌سازی کاربردی پایه Timeout

  • در مرورگرها:

    • رمز: یک عدد ساده که نشان دهنده شناسه وقفه است.
  const token = setTimeout(() => {}, 100);
  clearTimeout(token);
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  • در Node.js:

    • رمز: یک شی با چندین ویژگی و مرجع.
  const token = setTimeout(() => {});
  console.log(token);
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نمونه ای از Timeout Object در Node.js

Timeout {
  _idleTimeout: 1,
  _idlePrev: [TimersList],
  _idleNext: [TimersList],
  _idleStart: 4312,
  _onTimeout: [Function (anonymous)],
  _timerArgs: undefined,
  _repeat: null,
  _destroyed: false,
  [Symbol(refed)]: true,
  [Symbol(kHasPrimitive)]: false,
  [Symbol(asyncId)]: 78,
  [Symbol(triggerId)]: 6
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  • خواص: شامل ابرداده در مورد مهلت زمانی، ارجاع به اشیاء دیگر و توابع است.
  • موضوع: این ارجاعات مانع از جمع‌آوری زباله‌های شی زمان‌بندی می‌شوند، حتی پس از پاک‌سازی یا تکمیل.

مثال کلاسی که منجر به نشت حافظه می شود

class MyThing {
  constructor() {
    this.timeout = setTimeout(() => { /*...*/ }, INTERVAL);
  }

  clearTimeout() {
    clearTimeout(this.timeout);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  • مرجع دائمی: Timeout شی در حافظه باقی می ماند زیرا یک شی با ارجاع است نه یک عدد ساده.

تاثیر AsyncLocalStorage

  • AsyncLocalStorage: یک API جدید که حالت اضافی را به وقفه ها، وعده ها و سایر عملیات ناهمزمان متصل می کند.
  • مثال:
  const { AsyncLocalStorage } = require('node:async_hooks');
  const als = new AsyncLocalStorage();

  let t;
  als.run([...Array(10000)], () => {
    t = setTimeout(() => {
      const theArray = als.getStore();
    }, 100);
  });
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  • نتیجه: اکنون شی timeout ارجاع به یک آرایه بزرگ را از طریق یک نماد سفارشی دارد که حتی پس از پاک شدن یا تکمیل مهلت زمانی باقی می ماند.
  Timeout {
    [Symbol(kResourceStore)]: [Array] // reference to that large array is held here
  }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

راه حل پیشنهادی: استفاده از شناسه های اولیه

  • رویکرد: تبدیل کنید Timeout برای جلوگیری از نگهداری ارجاع به یک عدد اعتراض کنید.
  class MyThing {
    constructor() {
      this.timeout = +setTimeout(() => { /*...*/ }, INTERVAL);
    }

    clearTimeout() {
      clearTimeout(this.timeout);
    }
  }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  • مشکل فعلی: به دلیل وجود یک اشکال در Node.js، این رویکرد در حال حاضر باعث نشت حافظه غیرقابل بازیابی می شود.

راه حل: باطل کردن تهاجمی

  • استراتژی: برای کمک به جمع آوری زباله، مرجع وقفه را به صورت دستی پاک کنید.
  class MyThing {
    constructor() {
      this.timeout = setTimeout(() => {
        this.timeout = null;
        // Additional logic
      }, INTERVAL);
    }

    clearTimeout() {
      if (this.timeout) {
        clearTimeout(this.timeout);
        this.timeout = null;
      }
    }
  }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مفاهیم گسترده تر

  • موضوع گسترده: بسیاری از برنامه‌های Node.js از وقفه‌ها و بازه‌های زمانی استفاده می‌کنند که خطر نشت حافظه را افزایش می‌دهد.
  • بارگذاری مجدد کد داغ: تایم اوت های طولانی مدت یا مکرر می تواند مشکل را تشدید کند.
  • راه حل Next.js: وصله ها setTimeout و setInterval برای پاک کردن فواصل دوره ای، اما همچنان می تواند با اشکال Node.js مواجه شود.

ملاحظات بلند مدت

  • بهبودهای API: Node.js می تواند یک شی پراکسی سبک وزن را به جای کامل برگرداند Timeout شی، که مدیریت آن آسان تر و کمتر مستعد نشت است.
  • مدیریت AsyncLocalStorage: ارائه API برای جلوگیری از انتشار حالت غیر ضروری می تواند به کاهش نشت حافظه کمک کند.

نتیجه

  • مدیریت حافظه: توسعه‌دهندگان باید به‌دقت زمان‌بندی‌ها و مراجع آنها را مدیریت کنند تا از نشت حافظه جلوگیری کنند.
  • در انتظار رفع Node.js: رفع دائمی باگ Node.js برای مدیریت موثر حافظه بسیار مهم است.

درک این تفاوت‌ها و اتخاذ بهترین روش‌ها می‌تواند به کاهش نشت حافظه در برنامه‌های Node.js کمک کند و عملکرد و ثبات بهتری را تضمین کند.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا