অবজেক্ট পুল সহ স্ট্যাটিক মেমরি জাভাস্ক্রিপ্ট

ভূমিকা

তাই আপনি একটি ইমেল পাবেন যাতে বলা হয় যে আপনার ওয়েব-গেম/ওয়েব-অ্যাপ একটি নির্দিষ্ট সময়ের পরে কীভাবে খারাপভাবে পারফর্ম করছে, আপনি আপনার কোডটি খনন করে দেখেন, আপনি Chrome এর মেমরি পারফরম্যান্স টুলস না খোলা পর্যন্ত আলাদা কিছু দেখতে পাচ্ছেন না, এবং এটা দেখ:

আপনার মেমরি টাইমলাইন থেকে একটি স্ন্যাপশট

আপনার একজন সহকর্মী হাসে, কারণ তারা বুঝতে পারে যে আপনি একটি স্মৃতি-সম্পর্কিত কর্মক্ষমতা সমস্যা পেয়েছেন।

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

করাত-দাঁত বলতে কী বোঝায়

এইরকম একটি গ্রাফে, আপনি দেখতে পাচ্ছেন যে প্রচুর আবর্জনা সংগ্রহের ঘটনা ঘটছে, যা আপনার ওয়েব-অ্যাপগুলির কর্মক্ষমতার জন্য ক্ষতিকারক হতে পারে। এই নিবন্ধটি কীভাবে আপনার মেমরির ব্যবহার নিয়ন্ত্রণ করতে হয়, আপনার কর্মক্ষমতার উপর প্রভাব কমাতে পারে সে সম্পর্কে কথা বলবে।

আবর্জনা সংগ্রহ এবং কর্মক্ষমতা খরচ

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

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

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

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

মেমরি মন্থন হ্রাস করুন, আবর্জনা সংগ্রহ কর হ্রাস করুন

উল্লিখিত হিসাবে, একটি GC পালস ঘটবে যখন হিউরিস্টিকসের একটি সেট নির্ধারণ করে যে সেখানে যথেষ্ট নিষ্ক্রিয় বস্তু রয়েছে যা একটি পালস উপকারী হবে। যেমন, আবর্জনা সংগ্রাহক আপনার অ্যাপ্লিকেশন থেকে যে পরিমাণ সময় নেয় তা হ্রাস করার মূল চাবিকাঠি হল অত্যধিক বস্তু তৈরির এবং যতটা সম্ভব মুক্তির ক্ষেত্রে নির্মূল করা। ঘন ঘন বস্তু তৈরি/মুক্ত করার এই প্রক্রিয়াটিকে "মেমরি মন্থন" বলা হয়। আপনি যদি আপনার আবেদনের জীবদ্দশায় মেমরি মন্থন কমাতে পারেন, তাহলে আপনি আপনার মৃত্যুদন্ড থেকে GC যে সময় নেয় তাও কমিয়ে দেন। এর অর্থ হল আপনাকে তৈরি করা এবং ধ্বংস হওয়া বস্তুর সংখ্যা অপসারণ / হ্রাস করতে হবে, কার্যকরভাবে, আপনাকে মেমরি বরাদ্দ করা বন্ধ করতে হবে।

এই প্রক্রিয়াটি আপনার মেমরি গ্রাফটি এখান থেকে সরিয়ে নেবে:

আপনার মেমরি টাইমলাইন থেকে একটি স্ন্যাপশট

এর প্রতি:

স্ট্যাটিক মেমরি জাভাস্ক্রিপ্ট

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

স্ট্যাটিক-মেমরি জাভাস্ক্রিপ্টের দিকে যাচ্ছে

স্ট্যাটিক মেমরি জাভাস্ক্রিপ্ট হল এমন একটি কৌশল যা আপনার অ্যাপের শুরুতে প্রাক-বরাদ্দকরণ জড়িত, সমস্ত মেমরি যা তার জীবনকালের জন্য প্রয়োজন হবে, এবং সেই মেমরিটিকে কার্যকর করার সময় বস্তু হিসাবে আর প্রয়োজন নেই। আমরা কয়েকটি সহজ ধাপে এই লক্ষ্যে পৌঁছাতে পারি:

  1. ব্যবহারের পরিস্থিতির একটি পরিসরের জন্য প্রয়োজনীয় লাইভ মেমরি অবজেক্টের (প্রতি প্রকার) সর্বাধিক সংখ্যা কত তা নির্ধারণ করতে আপনার অ্যাপ্লিকেশনটি তৈরি করুন
  2. সেই সর্বাধিক পরিমাণ প্রাক-বরাদ্দ করতে আপনার কোডটি পুনরায় প্রয়োগ করুন এবং তারপরে প্রধান মেমরিতে যাওয়ার পরিবর্তে ম্যানুয়ালি আনুন/মুক্ত করুন।

বাস্তবে, # 1 অর্জনের জন্য আমাদের # 2 এর বিট করতে হবে, তাই আসুন সেখানে শুরু করি।

অবজেক্ট পুল

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

যেহেতু একটি অ্যাপ্লিকেশান রক্ষণাবেক্ষণ করে এমন বস্তুর ধরণের একটি ভিন্নধর্মী সেট রয়েছে, তাই অবজেক্ট পুলের সঠিক ব্যবহারের জন্য আপনার প্রতি টাইপের একটি পুল থাকা প্রয়োজন যা আপনার অ্যাপ্লিকেশনের রানটাইমের সময় উচ্চ-মন্থন অনুভব করে।

var newEntity = gEntityObjectPool.allocate();
newEntity.pos = {x: 215, y: 88};

//..... do some stuff with the object that we need to do

gEntityObjectPool.free(newEntity); //free the object when we're done
newEntity = null; //free this object reference

বেশিরভাগ অ্যাপ্লিকেশনের জন্য, নতুন অবজেক্ট বরাদ্দ করার প্রয়োজনের ক্ষেত্রে আপনি শেষ পর্যন্ত কিছু লেভেল-অফ হিট করবেন। আপনার অ্যাপ্লিকেশানের একাধিক রানের উপরে, আপনি এই ঊর্ধ্ব সীমাটি কী তা নিয়ে একটি দুর্দান্ত অনুভূতি পেতে সক্ষম হবেন এবং আপনার অ্যাপ্লিকেশনের শুরুতে সেই সংখ্যক অবজেক্ট প্রাক-বরাদ্দ করতে পারবেন।

প্রাক-বরাদ্দ করা বস্তু

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

তারপরে, আপনার অ্যাপের শিপিং সংস্করণে, আপনি একটি নির্দিষ্ট পরিমাণে সমস্ত অবজেক্ট পুল প্রাক-ভর্তি করার জন্য প্রাথমিক পর্যায়ে সেট করতে পারেন। এই আইনটি আপনার অ্যাপের সামনে সমস্ত অবজেক্ট ইনিশিয়ালাইজেশনকে ঠেলে দেবে এবং এটি কার্যকর করার সময় গতিশীলভাবে ঘটে যাওয়া বরাদ্দের পরিমাণ কমিয়ে দেবে।

function init() {
  //preallocate all our pools. 
  //Note that we keep each pool homogeneous wrt object types
  gEntityObjectPool.preAllocate(256);
  gDomObjectPool.preAllocate(888);
}

আপনি যে পরিমাণ চয়ন করেন তা আপনার আবেদনের আচরণের সাথে একটি দুর্দান্ত চুক্তি করে; কখনও কখনও তাত্ত্বিক সর্বোচ্চ সেরা বিকল্প নয়। উদাহরণস্বরূপ, গড় সর্বাধিক নির্বাচন করা আপনাকে অ পাওয়ার-ব্যবহারকারীদের জন্য একটি ছোট মেমরি পদচিহ্ন দিতে পারে।

একটি রূপালী বুলেট থেকে দূরে

অ্যাপ্লিকেশানগুলির একটি সম্পূর্ণ শ্রেণীবিভাগ রয়েছে যেখানে স্ট্যাটিক মেমরি বৃদ্ধির ধরণগুলি একটি জয় হতে পারে। সহকর্মী ক্রোম ডেভরেল রেনাটো মাঙ্গিনি উল্লেখ করেছেন যে, কিছু ত্রুটি রয়েছে।

উপসংহার

ওয়েবের জন্য জাভাস্ক্রিপ্ট আদর্শ হওয়ার একটি কারণ হল এটি একটি দ্রুত, মজাদার এবং সহজ ভাষা শুরু করার জন্য নির্ভর করে৷ এটি মূলত সিনট্যাক্স বিধিনিষেধের কম বাধা এবং আপনার পক্ষ থেকে মেমরির সমস্যাগুলি পরিচালনা করার কারণে। আপনি দূরে কোড করতে পারেন এবং এটি নোংরা কাজের যত্ন নিতে দিন। তবে HTML5 গেমের মতো উচ্চ-পারফরম্যান্স ওয়েব অ্যাপ্লিকেশনগুলির জন্য, GC প্রায়শই সমালোচিতভাবে প্রয়োজনীয় ফ্রেম রেট খেয়ে ফেলতে পারে, যা শেষ ব্যবহারকারীর অভিজ্ঞতা হ্রাস করে। কিছু সতর্ক যন্ত্র এবং অবজেক্ট পুল গ্রহণের মাধ্যমে, আপনি আপনার ফ্রেমের হারের উপর এই বোঝা কমাতে পারেন এবং আরও দুর্দান্ত জিনিসগুলির জন্য সেই সময়টিকে পুনরায় দাবি করতে পারেন।

সোর্স কোড

ওয়েবে চারপাশে ভাসমান অবজেক্ট পুলের প্রচুর বাস্তবায়ন রয়েছে, তাই আমি আপনাকে অন্য একটি দিয়ে বিরক্ত করব না। পরিবর্তে, আমি আপনাকে এগুলি নির্দেশ করব, যার প্রতিটিরই নির্দিষ্ট বাস্তবায়নের সূক্ষ্মতা রয়েছে; যা গুরুত্বপূর্ণ, বিবেচনা করে প্রতিটি অ্যাপ্লিকেশন ব্যবহারের নির্দিষ্ট বাস্তবায়নের প্রয়োজন থাকতে পারে।

তথ্যসূত্র