برنامه نویسی

node.js آخرالزمان حافظه: چرا برنامه شما روی پرونده های بزرگ می میرد (و چگونه می توان آن را برای همیشه متوقف کرد)

اسکریپت Node.js شما کاملاً با داده های آزمون کار می کند. سپس آن را به یک پرونده ورود به سیستم 10 گیگابایتی واقعی تغذیه می کنید. ناگهان: سقوطبشر بدون هشدار ، فقط ENOMEMبشر در اینجا به همین دلیل است که حتی توسعه دهندگان فصلی این اشتباه را انجام می دهند – و راه حل ضد گلوله.


ریشه همه شر: fs.readFile

fs.readFile معادل ریختن محتویات کامیون کمپرسی در اتاق نشیمن شماست. بار می کند هر بایت قبل از اینکه بتوانید آن را لمس کنید ، به رم وارد شوید. مشاهده:

// Processing a 3GB database dump? Enjoy 3GB RAM usage
fs.readFile('./mega-database.sql', 'utf8', (err, data) => {
  parseSQL(data); // Hope you have 3GB to spare
});
حالت تمام صفحه را وارد کنید

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

  • ابزارهای CLI پردازش تصادف CSV های بزرگ
  • خط لوله داده روی پرونده های ویدیویی منفجر شوید
  • خدمات پس زمینه ساعت 3 صبح بی صدا بمیرید

این “کد بد” نیست – چگونه است fs.readFile عمل می کند و به همین دلیل است که سیستم تولید شما فاجعه بار شکست می خورد.


جریان: تکنیک Ninja Memory

جریان داده ها مانند یک کمربند نقاله – تکه های کوچک وارد می شوند ، پردازش می شوند ، سپس حافظه را برای همیشه رها می کنند. بدون انفجار RAM:

// Process 100GB file with ~50MB memory
const stream = fs.createReadStream('./giant-dataset.csv');

stream.on('data', (chunk) => {
  analyzeChunk(chunk); // Work with 64KB-1MB pieces
});

stream.on('end', () => {
  console.log('Processed entire file without going nuclear');
});
حالت تمام صفحه را وارد کنید

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


قتل عام دنیای واقعی: پردازش پرونده

رویکرد خودکشی (اشتباه مشترک)

// Data import script that crashes on big files
function importUsers() {
  fs.readFile('./users.json', (err, data) => {
    JSON.parse(data).forEach(insertIntoDatabase); // 💀
  });
}
حالت تمام صفحه را وارد کنید

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

راهنمای زنده ماندن جریان (روش صحیح)

// Processes 50GB JSON file without memory issues
const ndjsonStream = fs.createReadStream('./users.ndjson');
const jsonParser = new TransformStream({ /* parse line-by-line */ });

ndjsonStream.pipe(jsonParser)
  .on('data', (user) => insertIntoDatabase(user));
حالت تمام صفحه را وارد کنید

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

جریان ها پرونده های در مقیاس Terabyte را مانند آنها هیچ چیز ندارند. برنامه شما پاسخگو می ماند – بدون خراب شدن.


نکته حرفه ای: جریان + خطوط لوله = غیرقابل توقف

جریان ها را با node.js 'ترکیب کنید pipeline برای پردازش ضد خطا:

const { pipeline } = require('stream');
const zlib = require('zlib');

// Compress 20GB log file with constant memory
pipeline(
  fs.createReadStream('./server.log'),
  zlib.createGzip(), // Compress chunk-by-chunk
  fs.createWriteStream('./server.log.gz'),
  (err) => {
    if (err) console.error('Pipeline failed:', err);
    else console.log('Compressed 20GB file like a boss');
  }
);
حالت تمام صفحه را وارد کنید

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


چه زمانی از کدام سلاح استفاده کنیم

fs.readFile (با دقت کار کنید):

  • پرونده های پیکربندی (<5MB)
  • دارایی های استاتیک کوچک (نمادها ، JSON کوچک)
  • فقط وقتی کاملاً به تمام داده های حافظه احتیاج دارید

fs.createReadStream (انتخاب پیش فرض):

  • پردازش ورود به سیستم
  • رمزگذاری رسانه/رمزگذاری
  • واردات/صادرات پایگاه داده
  • هر پرونده ای بزرگتر از رم تلفن شما

حقیقت خشن

fs.readFile نسخه Node.js از یک اسلحه بارگذاری شده است – در محیط های کنترل شده ، در تولید کشنده است. جریان ها تکنیک های “پیشرفته” نیستند. آنها مهارت های اساسی بقای برای هر توسعه دهنده Node.js جدی.

دفعه بعد که می نویسید fs.readFile، بپرسید: “آیا این پرونده هرگز رشد خواهد کرد؟” اگر جواب مثبت است (و همیشه هست) ، شما فقط نشت حافظه خود را پیدا کرده اید. تغییر به جریان –قبل از اینکه پیجر شما نیمه شب خاموش شود.

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

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

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

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