মেমরি সংক্রান্ত সমস্যার সমাধান করা

Kayce Basques
Kayce Basques

মেমরি লিক, মেমরি ব্লট ও ঘন ঘন গার্বেজ কালেকশন সহ পৃষ্ঠার পারফর্ম্যান্সকে প্রভাবিত করে এমন মেমরি সংক্রান্ত সমস্যা খুঁজে পেতে, কীভাবে Chrome ও DevTools ব্যবহার করতে হয় তা জানুন।

সারাংশ

  • Chrome টাস্ক ম্যানেজারের সাহায্যে আপনার পৃষ্ঠা কতটা মেমরি ব্যবহার করছে তা খুঁজে বের করুন।
  • টাইমলাইন রেকর্ডিংয়ের মাধ্যমে সময়ের সাথে সাথে মেমরির ব্যবহার দেখুন।
  • হিপ স্ন্যাপশটের মাধ্যমে আলাদা করা DOM ট্রি (মেমরি লিকের সাধারণ কারণ) শনাক্ত করুন।
  • অ্যালোকেশন টাইমলাইন রেকর্ডিংয়ের মাধ্যমে আপনার JS হিপে কখন নতুন মেমরি বরাদ্দ করা হচ্ছে তা খুঁজে বের করুন।
  • জাভাস্ক্রিপ্ট রেফারেন্সের মাধ্যমে বজায় রাখা আলাদা করা এলিমেন্ট শনাক্ত করুন।

এক নজরে

RAIL পারফর্ম্যান্স মডেলের মূল উদ্দেশ্য হল, আপনার পারফর্ম্যান্স সংক্রান্ত প্রচেষ্টার মূল লক্ষ্য যেন আপনার ব্যবহারকারীরা হন।

মেমরি সংক্রান্ত সমস্যা গুরুত্বপূর্ণ কারণ ব্যবহারকারীরা প্রায়ই এটি বুঝতে পারেন। ব্যবহারকারীরা নিম্নলিখিত উপায়ে মেমরি সংক্রান্ত সমস্যা বুঝতে পারেন:

  • সময়ের সাথে সাথে কোনও পৃষ্ঠার পারফর্ম্যান্স ক্রমশ খারাপ হতে থাকে। এটি সম্ভবত মেমরি লিকের লক্ষণ। পৃষ্ঠায় কোনও বাগ থাকলে, সময়ের সাথে সাথে পৃষ্ঠাটি আরও বেশি মেমরি ব্যবহার করতে থাকে, একেই মেমরি লিক বলা হয়।
  • কোনও পৃষ্ঠার পারফর্ম্যান্স ধারাবাহিকভাবে খারাপ। এটি সম্ভবত মেমরি ব্লটের লক্ষণ। পৃষ্ঠা লোড হওয়ার গতি অপ্টিমাইজ করার জন্য যতটা মেমরি প্রয়োজন, কোনও পৃষ্ঠা তার চেয়ে বেশি মেমরি ব্যবহার করলে তাকে মেমরি ব্লট বলা হয়।
  • কোনও পৃষ্ঠার পারফর্ম্যান্স দেরি করে বা ঘনঘন পজ হয়ে যায় বলে মনে হয়। এটি সম্ভবত ঘন ঘন আবর্জনা সংগ্রহের একটি লক্ষণ। ব্রাউজার মেমরি রিক্লেম করলে তাকে গার্বেজ কালেকশন বলা হয়। ব্রাউজার সিদ্ধান্ত নেয় যে এটি কখন হবে। সংগ্রহ করার সময়, সব স্ক্রিপ্ট এক্সিকিউশন পজ করা হয়। তাই ব্রাউজার যদি অনেক বেশি গার্বেজ সংগ্রহ করে, তাহলে স্ক্রিপ্ট এক্সিকিউশন অনেক বেশি পজ হয়ে যাবে।

মেমরি ব্লট: কতটা "খুব বেশি"?

মেমরি লিক সহজেই সংজ্ঞায়িত করা যায়। কোনও সাইট যদি ক্রমশ আরও বেশি মেমরি ব্যবহার করে, তাহলে বুঝতে হবে যে লিক হয়েছে। তবে মেমরি ব্লট চিহ্নিত করা একটু কঠিন। "খুব বেশি মেমরি ব্যবহার করা" বলতে কী বোঝায়?

এখানে কোনও নির্দিষ্ট সংখ্যা নেই, কারণ বিভিন্ন ডিভাইস ও ব্রাউজারের ক্ষমতা আলাদা আলাদা হয়। যে পৃষ্ঠাটি হাই-এন্ড স্মার্টফোনে মসৃণভাবে চলে, সেটি লো-এন্ড স্মার্টফোনে ক্র্যাশ করতে পারে।

এখানে মূল বিষয় হল RAIL মডেল ব্যবহার করা এবং আপনার ব্যবহারকারীদের উপর ফোকাস করা। আপনার ব্যবহারকারীদের মধ্যে কোন ডিভাইসগুলি জনপ্রিয় তা খুঁজে বের করুন এবং তারপরে সেই ডিভাইসগুলিতে আপনার পৃষ্ঠা পরীক্ষা করুন। অভিজ্ঞতা যদি ক্রমাগত খারাপ হতে থাকে, তাহলে পৃষ্ঠাটি হয়ত সেইসব ডিভাইসের মেমরি ক্ষমতার চেয়ে বেশি মেমরি ব্যবহার করছে।

Chrome টাস্ক ম্যানেজারের মাধ্যমে রিয়েল-টাইমে মেমরির ব্যবহার মনিটর করুন

মেমরি সংক্রান্ত সমস্যা তদন্ত করার জন্য Chrome টাস্ক ম্যানেজার ব্যবহার করুন। টাস্ক ম্যানেজার হল একটি রিয়েল-টাইম মনিটর যা আপনাকে জানায় যে কোনও পৃষ্ঠা কতটা মেমরি ব্যবহার করছে।

  1. টাস্ক ম্যানেজার খুলতে Shift+Esc প্রেস করুন অথবা Chrome-এর মূল মেনুতে গিয়ে আরও টুল > টাস্ক ম্যানেজার বিকল্প বেছে নিন।

    টাস্ক ম্যানেজার খোলা হচ্ছে।

  2. টাস্ক ম্যানেজারের টেবিল হেডারে মাউসের ডানদিকের বোতামে ক্লিক করে জাভাস্ক্রিপ্ট মেমরি চালু করুন।

    টাস্ক ম্যানেজার হেডারে JS মেমরি চালু করা হচ্ছে।

আপনার পৃষ্ঠা কীভাবে মেমরি ব্যবহার করছে সেই সম্পর্কে এই দুটি কলাম আপনাকে বিভিন্ন তথ্য দেয়:

  • মেমরি ফুটপ্রিন্ট কলামটি OS মেমরিকে দেখায়। DOM নোড OS মেমরিতে স্টোর করা হয়। এই মান বাড়তে থাকলে, DOM নোড তৈরি হচ্ছে।
  • জাভাস্ক্রিপ্ট মেমরি কলামটি JS হিপকে উপস্থাপন করে। এই কলামে দুটি ভ্যালু আছে। আপনি যে ভ্যালু দেখতে চান সেটি হল লাইভ নম্বর (বন্ধনীতে থাকা নম্বর)। লাইভ নম্বর দেখায় যে আপনার পৃষ্ঠার অ্যাক্সেসযোগ্য অবজেক্টগুলি কতটা মেমরি ব্যবহার করছে। এই সংখ্যাটি বৃদ্ধি পেলে, হয় নতুন অবজেক্ট তৈরি হচ্ছে, অথবা আগে থেকে থাকা অবজেক্টের সংখ্যা বাড়ছে।

    জাভাস্ক্রিপ্ট মেমরি হেডার চালু থাকা টাস্ক ম্যানেজার।

পারফর্ম্যান্স রেকর্ডিংয়ের মাধ্যমে মেমরি লিক ভিজ্যুয়ালাইজ করুন

এছাড়াও, আপনার তদন্তের আরেকটি সূচনা বিন্দু হিসেবে পারফর্ম্যান্স প্যানেল ব্যবহার করতে পারেন। পারফর্ম্যান্স প্যানেল আপনাকে সময়ের সাথে সাথে কোনও পৃষ্ঠার মেমরি ব্যবহার ভিজ্যুয়ালাইজ করতে সাহায্য করে।

  1. DevTools-এ পারফর্ম্যান্স প্যানেল খুলুন।
  2. মেমরি চেকবক্স চালু করুন।
  3. রেকর্ডিং করুন।

পারফর্ম্যান্স মেমরি রেকর্ডিং দেখাতে, নিম্নলিখিত কোডটি বিবেচনা করুন:

var x = [];

function grow() {
  for (var i = 0; i < 10000; i++) {
    document.body.appendChild(document.createElement('div'));
  }
  x.push(new Array(1000000).join('x'));
}

document.getElementById('grow').addEventListener('click', grow);

কোডে উল্লেখ করা বোতামটি যতবার প্রেস করা হয়, ততবার ডকুমেন্টের বডিতে দশ হাজার div নোড যোগ করা হয় এবং x অ্যারেতে দশ লক্ষ x অক্ষরের একটি স্ট্রিং পুশ করা হয়। এই কোড রান করলে, নিচের স্ক্রিনশটের মতো টাইমলাইন রেকর্ডিং তৈরি হয়:

উপার্জন বৃদ্ধির একটি সহজ উদাহরণ।

প্রথমে, ইউজার ইন্টারফেসের ব্যাখ্যা। ওভারভিউ প্যানে (NET-এর নিচে) HEAP গ্রাফ JS হিপকে দেখায়। এক নজরে পেনের নিচে কাউন্টার পেন আছে। এখানে আপনি JS হিপ (এক নজরে প্যানে HEAP গ্রাফের মতো), ডকুমেন্ট, DOM নোড, লিসেনার ও GPU মেমরি অনুযায়ী মেমরির ব্যবহার দেখতে পাবেন। কোনও চেকবক্স বন্ধ করলে, সেটি গ্রাফ থেকে লুকানো হয়।

এখন, স্ক্রিনশটের সাথে তুলনা করে কোডের বিশ্লেষণ। আপনি নোড কাউন্টার (সবুজ গ্রাফ) দেখলে বুঝতে পারবেন যে এটি কোডের সাথে মিলে যাচ্ছে। নোডের সংখ্যা বিচ্ছিন্ন ধাপে বৃদ্ধি পায়। আপনি ধরে নিতে পারেন যে নোড কাউন্টে প্রতিটি বৃদ্ধি হল grow()-এ একটি কল। JS হিপ গ্রাফ (নীল গ্রাফ) এত সহজ নয়। সেরা পদ্ধতি মেনে, প্রথম ডিপ আসলে একটি জোরপূর্বক আবর্জনা সংগ্রহ (আবর্জনা সংগ্রহ করুন বোতাম টিপে অর্জন করা হয়)। রেকর্ডিং এগিয়ে যাওয়ার সাথে সাথে আপনি দেখতে পাবেন যে JS হিপ সাইজ স্পাইক করছে। এটি স্বাভাবিক এবং প্রত্যাশিত: JavaScript কোড প্রতিটি বোতাম ক্লিকে DOM নোড তৈরি করছে এবং দশ লক্ষ অক্ষরের স্ট্রিং তৈরি করার সময় অনেক কাজ করছে। এখানে মূল বিষয়টি হল, JS হিপ শুরু হওয়ার থেকে বেশি পরিমাণে শেষ হয় (এখানে "শুরু" বলতে বোঝায়, জোর করে গার্বেজ কালেকশনের পরের পয়েন্ট)। বাস্তবে, আপনি যদি JS হিপ সাইজ বা নোড সাইজ বৃদ্ধির এই প্যাটার্নটি দেখেন, তাহলে এর অর্থ সম্ভবত মেমরি লিক।

হিপ স্ন্যাপশটের সাহায্যে ডিটাচ করা DOM ট্রি মেমরি লিক খুঁজে বের করুন

DOM নোড তখনই গার্বেজ কালেক্ট করা যেতে পারে যখন পৃষ্ঠার DOM ট্রি বা জাভাস্ক্রিপ্ট কোড থেকে এটির কোনও রেফারেন্স থাকে না। কোনও নোডকে "বিচ্ছিন্ন" বলা হয় যখন এটি DOM ট্রি থেকে সরানো হয় কিন্তু কিছু জাভাস্ক্রিপ্ট এখনও এটি রেফারেন্স করে। আলাদা করা DOM নোড হল মেমরি লিকের সাধারণ কারণ। এই বিভাগ থেকে আপনি জানতে পারবেন যে কীভাবে DevTools-এর হিপ প্রোফাইলার ব্যবহার করে ডিটাচ করা নোড শনাক্ত করতে হয়।

আলাদা করা DOM নোডের একটি সহজ উদাহরণ এখানে দেওয়া হল।

var detachedTree;

function create() {
  var ul = document.createElement('ul');
  for (var i = 0; i < 10; i++) {
    var li = document.createElement('li');
    ul.appendChild(li);
  }
  detachedTree = ul;
}

document.getElementById('create').addEventListener('click', create);

কোডে উল্লেখ করা বোতামে ক্লিক করলে দশটি li চিলড্রেন সহ একটি ul নোড তৈরি হয়। এইসব নোড কোড দ্বারা রেফারেন্স করা হয় কিন্তু DOM ট্রিতে থাকে না, তাই সেগুলি বিচ্ছিন্ন হয়ে যায়।

আলাদা করা নোড শনাক্ত করার একটি উপায় হল হিপ স্ন্যাপশট। নাম থেকে বোঝা যায়, হিপ স্ন্যাপশট আপনাকে দেখায় যে স্ন্যাপশট নেওয়ার সময় আপনার পৃষ্ঠার JS অবজেক্ট ও DOM নোডের মধ্যে কীভাবে মেমরি ডিস্ট্রিবিউট করা হয়েছে।

স্ন্যাপশট তৈরি করতে, DevTools খুলে মেমরি প্যানেলে যান, হিপ স্ন্যাপশট রেডিও বোতাম বেছে নিন এবং তারপরে স্ন্যাপশট নিন বোতামে প্রেস করুন।

হিপ স্ন্যাপশট নিন রেডিও বোতাম বেছে নেওয়া হয়েছে।

স্ন্যাপশট প্রসেস ও লোড হতে কিছুটা সময় লাগতে পারে। এটি শেষ হয়ে গেলে, বাঁদিকের প্যানেল থেকে এটি বেছে নিন (হিপ স্ন্যাপশট নামে)।

আলাদা করা DOM ট্রি সার্চ করতে ক্লাস ফিল্টার ইনপুট বক্সে Detached টাইপ করুন।

আলাদা করা যায় এমন নোডের জন্য ফিল্টার করা হচ্ছে।

বিচ্ছিন্ন ট্রি তদন্ত করতে ক্যারেট বড় করুন।

আলাদা হয়ে যাওয়া গাছ নিয়ে তদন্ত করা হচ্ছে।

আরও তদন্ত করতে কোনও নোডে ক্লিক করুন। অবজেক্ট প্যানে আপনি কোড সম্পর্কে আরও তথ্য দেখতে পাবেন যা এটিকে রেফার করছে। যেমন, নিম্নলিখিত স্ক্রিনশটে আপনি দেখতে পাবেন যে detachedTree ভেরিয়েবলটি নোডকে রেফারেন্স করছে। এই নির্দিষ্ট মেমরি লিক ঠিক করতে, আপনি detachedTree ব্যবহার করে এমন কোড স্টাডি করবেন এবং নিশ্চিত করবেন যে নোডের আর প্রয়োজন না থাকলে এটি যেন নোডের রেফারেন্স সরিয়ে দেয়।

বিচ্ছিন্ন নোড খতিয়ে দেখা হচ্ছে।

অ্যালোকেশন টাইমলাইনের সাহায্যে জাভাস্ক্রিপ্ট হিপ মেমরি লিকেজ শনাক্ত করা

অ্যালোকেশন টাইমলাইন হল আরেকটি টুল যা আপনার JS হিপে মেমরি লিক ট্র্যাক করতে সাহায্য করতে পারে।

অ্যালোকেশন টাইমলাইন দেখানোর জন্য নিম্নলিখিত কোডটি বিবেচনা করুন:

var x = [];

function grow() {
  x.push(new Array(1000000).join('x'));
}

document.getElementById('grow').addEventListener('click', grow);

কোডে উল্লেখ করা বোতামটি যতবার পুশ করা হয়, ততবার দশ লক্ষ অক্ষরের একটি স্ট্রিং x অ্যারেতে যোগ করা হয়।

অ্যালোকেশন টাইমলাইন রেকর্ড করতে, DevTools খুলুন, মেমরি প্যানেলে যান, টাইমলাইনে অ্যালোকেশন রেডিও বোতাম বেছে নিন, রেকর্ড করুন বোতাম প্রেস করুন, যে অ্যাকশনের কারণে মেমরি লিক হচ্ছে বলে আপনার সন্দেহ হচ্ছে সেটি করুন এবং তারপরে কাজ হয়ে গেলে রেকর্ডিং বন্ধ করুন বোতাম প্রেস করুন।

রেকর্ড করার সময়, অ্যালোকেশন টাইমলাইনে কোনও নীল বার দেখা যাচ্ছে কিনা তা লক্ষ্য করুন, যেমনটি নিচের স্ক্রিনশটে দেখানো হয়েছে।

পারফর্ম্যান্স টাইমলাইনে নতুন অ্যালোকেশন।

এই নীল বারগুলি নতুন মেমরি অ্যালোকেশন দেখায়। এই নতুন মেমরি অ্যালোকেশনগুলি মেমরি লিকের জন্য আপনার ক্যান্ডিডেট। আপনি কোনও বারে জুম করে Constructor প্যানে ফিল্টার করতে পারেন যাতে শুধুমাত্র নির্দিষ্ট টাইমফ্রেমের মধ্যে অ্যালোকেট করা অবজেক্ট দেখা যায়।

জুম করা অ্যালোকেশন টাইমলাইন।

অবজেক্ট প্যানে অবজেক্ট সম্পর্কে আরও বিবরণ দেখতে, অবজেক্টটি বড় করুন এবং এর ভ্যালুতে ক্লিক করুন। যেমন, নিচের স্ক্রিনশটে, নতুন বরাদ্দ করা অবজেক্টের বিবরণ দেখে, আপনি দেখতে পাবেন যে এটি Window স্কোপে x ভেরিয়েবলে বরাদ্দ করা হয়েছে।

স্ট্রিং অ্যারের অবজেক্টের বিবরণ।

ফাংশন অনুযায়ী মেমরি অ্যালোকেশন ইনভেস্টিগেট করুন

JavaScript ফাংশন অনুযায়ী মেমরি অ্যালোকেশন দেখতে, মেমরি প্যানেলে অ্যালোকেশন স্যাম্পলিং প্রোফাইলের ধরন ব্যবহার করুন।

মেমরি প্যানেলে অ্যালোকেশন স্যাম্পলিং প্রোফাইলার।

  1. অ্যালোকেশন স্যাম্পলিং রেডিও বোতাম বেছে নিন। পৃষ্ঠায় কোনও কর্মী থাকলে, আপনি জাভাস্ক্রিপ্ট VM ইনস্ট্যান্স বেছে নিন উইন্ডো থেকে প্রোফাইলিং টার্গেট হিসেবে সেটি বেছে নিতে পারবেন।
  2. শুরু করুন বোতাম প্রেস করুন।
  3. আপনি যে পৃষ্ঠাটি তদন্ত করতে চান সেখানে অ্যাকশনগুলি পারফর্ম করুন।
  4. আপনার সব অ্যাকশন সম্পূর্ণ হয়ে গেলে বন্ধ করুন বোতামে প্রেস করুন।

DevTools আপনাকে ফাংশন অনুযায়ী মেমরি অ্যালোকেশনের ব্রেকডাউন দেখায়। ডিফল্ট ভিউ হল Heavy (Bottom Up), যা সবচেয়ে বেশি মেমরি বরাদ্দ করা ফাংশনগুলিকে উপরে দেখায়।

অ্যালোকেশন প্রোফাইল ফলাফলের পৃষ্ঠা।

JS রেফারেন্সের মাধ্যমে ধরে রাখা অবজেক্ট শনাক্ত করা

আলাদা করা এলিমেন্ট প্রোফাইল আপনাকে আলাদা করা এলিমেন্ট দেখায় যেগুলি থেকে যায় কারণ জাভাস্ক্রিপ্ট কোড সেগুলিকে রেফারেন্স করে।

সঠিক HTML নোড ও নোডের সংখ্যা দেখতে আলাদা করা এলিমেন্ট প্রোফাইল রেকর্ড করুন।

আলাদা করা হয়েছে এমন এলিমেন্ট প্রোফাইলের উদাহরণ।

ঘন ঘন গার্বেজ সংগ্রহ করার জায়গা চিহ্নিত করুন

আপনার পৃষ্ঠা ঘন ঘন পজ হয়ে যাচ্ছে বলে মনে হলে, আপনার গার্বেজ কালেকশন সংক্রান্ত সমস্যা থাকতে পারে।

ঘন ঘন গার্বেজ কালেকশন শনাক্ত করতে আপনি Chrome টাস্ক ম্যানেজার বা টাইমলাইন মেমরি রেকর্ডিংয়ের মধ্যে যেকোনও একটি ব্যবহার করতে পারেন। টাস্ক ম্যানেজারে, ঘন ঘন ওঠা-নামা করা মেমরি বা জাভাস্ক্রিপ্ট মেমরি ভ্যালু ঘন ঘন গার্বেজ কালেকশনকে বোঝায়। টাইমলাইন রেকর্ডিংয়ে, ঘন ঘন ওঠা ও নামা JS হিপ বা নোড কাউন্ট গ্রাফ ঘন ঘন গার্বেজ কালেকশন নির্দেশ করে।

সমস্যাটি শনাক্ত করার পরে, আপনি একটি অ্যালোকেশন টাইমলাইন রেকর্ডিং ব্যবহার করে খুঁজে বের করতে পারেন যে কোথায় মেমরি বরাদ্দ করা হচ্ছে এবং কোন ফাংশনগুলি বরাদ্দের কারণ হচ্ছে।