আপনার অ্যাপের মেমরি পরিচালনা করুন

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

র‍্যান্ডম-অ্যাক্সেস মেমরি (RAM) যেকোনো সফটওয়্যার ডেভেলপমেন্ট পরিবেশের জন্য একটি মূল্যবান সম্পদ, এবং এটি একটি মোবাইল অপারেটিং সিস্টেমের জন্য আরও বেশি মূল্যবান, যেখানে ফিজিক্যাল মেমরি প্রায়শই সীমিত থাকে। যদিও অ্যান্ড্রয়েড রানটাইম (ART) এবং ডালভিক ভার্চুয়াল মেশিন উভয়ই নিয়মিত গার্বেজ কালেকশন করে, এর মানে এই নয় যে আপনার অ্যাপ কখন এবং কোথায় মেমরি বরাদ্দ ও মুক্ত করে তা আপনি উপেক্ষা করতে পারেন। আপনাকে এখনও মেমরি লিক তৈরি করা এড়াতে হবে—যা সাধারণত স্ট্যাটিক মেম্বার ভেরিয়েবলে অবজেক্ট রেফারেন্স ধরে রাখার কারণে ঘটে—এবং লাইফসাইকেল কলব্যাক দ্বারা সংজ্ঞায়িত সঠিক সময়ে যেকোনো Reference অবজেক্ট মুক্ত করতে হবে।

আপনার অ্যাপের কোড এবং রিসোর্স ফুটপ্রিন্ট হ্রাস করুন।

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

R8 সক্রিয় করে অ্যাপের সামগ্রিক আকার হ্রাস করুন

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

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

নিয়মকানুন বুঝুন এবং মেনে চলুন।

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

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

  • যেসব বৈশ্বিক নিয়ম এড়িয়ে চলতে হবে:
    • -dontoptimize : সম্পূর্ণ অ্যাপের জন্য অপটিমাইজেশন পুরোপুরি নিষ্ক্রিয় করে দেয়, যার ফলে এক্সিকিউটেবল ফাইলগুলো আকারে বড় ও ধীরগতির হয়।
    • -dontshrink : অব্যবহৃত কোড এবং রিসোর্স অপসারণ প্রতিরোধ করে।
    • -dontobfuscate : নাম সংক্ষিপ্তকরণ প্রতিরোধ করে, ফলে মূল্যবান মেমরি সাশ্রয়ের সুযোগ হাতছাড়া হয় (বিশেষ করে বড় অ্যাপের ক্ষেত্রে)।
  • প্যাকেজ-ব্যাপী ওয়াইল্ডকার্ড ব্যবহার পরিহার করুন: -keep class com.example.package.** { *; } এর মতো ব্যাপক নিয়মগুলো R8-কে সেই প্যাকেজের প্রতিটি ক্লাস, ফিল্ড এবং মেথড সংরক্ষণ করতে বাধ্য করে। এর ফলে সেই প্যাকেজের কোড অপসারণ, অপ্টিমাইজ বা মিনিফাই করার ক্ষেত্রে R8-এর ক্ষমতা সম্পূর্ণরূপে বন্ধ হয়ে যায়।

  • ডিফল্ট R8 কনফিগারেশন ফাইলটি ব্যবহার করুন: সর্বদা proguard-android-optimize.txt ব্যবহার করুন।

কিপ রুল লেখার বিষয়ে আরও তথ্যের জন্য, ‘কিপ রুল সম্পর্কে’ দেখুন। কোন নির্দিষ্ট প্যাটার্ন ব্যবহার করতে হবে এবং কোনটি এড়িয়ে চলতে হবে, তা জানতে ‘কিপ রুলের সর্বোত্তম অনুশীলন’ দেখুন।

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

বাহ্যিক লাইব্রেরি ব্যবহারে সতর্ক থাকুন।

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

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

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

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

ডিপেন্ডেন্সি ইনজেকশনের জন্য হিল্ট ব্যবহার করুন

ডিপেন্ডেন্সি ইনজেকশন ফ্রেমওয়ার্কগুলো আপনার লেখা কোডকে সরল করতে পারে এবং একটি অভিযোজনযোগ্য পরিবেশ প্রদান করতে পারে, যা টেস্টিং এবং অন্যান্য কনফিগারেশন পরিবর্তনের জন্য উপযোগী।

আপনি যদি আপনার অ্যাপে কোনো ডিপেন্ডেন্সি ইনজেকশন ফ্রেমওয়ার্ক ব্যবহার করতে চান, তবে Hilt ব্যবহার করার কথা ভাবতে পারেন। এটি অ্যান্ড্রয়েডের জন্য প্রস্তাবিত ইনজেকশন লাইব্রেরি যা Dagger-এর উপরে চলে। Hilt আপনার অ্যাপের কোড স্ক্যান করার জন্য রিফ্লেকশন ব্যবহার করে না। আপনি অপ্রয়োজনীয় রানটাইম খরচ বা মেমরি ব্যবহার ছাড়াই অ্যান্ড্রয়েড অ্যাপে Hilt-এর স্ট্যাটিক কম্পাইল-টাইম ইমপ্লিমেন্টেশন ব্যবহার করতে পারেন।

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

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

ছবি লোড করার ক্ষেত্রে সচেতন হোন।

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

উদাহরণস্বরূপ, বেশিরভাগ বিটম্যাপ ARGB_8888 কনফিগারেশন ব্যবহার করে, যার অর্থ প্রতিটি পিক্সেলের জন্য ৪ বাইট মেমরির প্রয়োজন হয়—লাল, সবুজ, নীল এবং আলফা (স্বচ্ছতা)-র জন্য এক বাইট করে। যদি আপনার কাছে একটি ১০০ কিলোবাইটের JPEG ফাইল থাকে এবং আপনি এটিকে ১০০০×১০০০ পিক্সেলের ভিউতে প্রদর্শন করেন, তাহলে বিটম্যাপটির ঐ ১০,০০,০০০ পিক্সেলের প্রতিটির জন্য ৪ বাইট করে মেমরির প্রয়োজন হবে, যা মোট ৪ মেগাবাইট মেমরি খরচ করবে।

আপনার ইমেজের ব্যবহার অপ্টিমাইজ করার জন্য বেশ কিছু উপায় রয়েছে। উদাহরণস্বরূপ, ইমেজ লোডিং লাইব্রেরি ব্যবহার করে আপনি অপ্রয়োজনীয় মেমোরি মুক্ত করতে পারেন। কীভাবে দক্ষতার সাথে ইমেজ পরিচালনা করা যায়, সে সম্পর্কে জানতে ‘Optimizing bitmap images’ দেখুন।

উপলব্ধ মেমরি এবং মেমরি ব্যবহার নিরীক্ষণ করুন

আপনার অ্যাপের মেমরি ব্যবহারের সমস্যাগুলো সমাধান করার আগে আপনাকে অবশ্যই সেগুলো খুঁজে বের করতে হবে। অ্যান্ড্রয়েড স্টুডিও মেমরি প্রোফাইলার আপনাকে নিম্নলিখিত উপায়ে মেমরির সমস্যা খুঁজে বের করতে এবং নির্ণয় করতে সাহায্য করে:

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

আপনার প্রোডাকশন অ্যাপ চালানো ব্যবহারকারীদের ডেটার উপর ভিত্তি করে মেমরি সমস্যা নির্ণয় করার জন্য আপনি আরও কিছু টুল ব্যবহার করতে পারেন:

ঘটনাগুলির প্রতিক্রিয়ায় স্মৃতি মুক্ত করুন

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

আপনার onTrimMemory এর বাস্তবায়নে, শুধুমাত্র TRIM_MEMORY_UI_HIDDEN এবং TRIM_MEMORY_BACKGROUND ইভেন্টগুলোর উপর মনোযোগ দিন। (অ্যান্ড্রয়েড ১৪ থেকে শুরু করে, সিস্টেম অন্যান্য লিগ্যাসি কনস্ট্যান্টগুলোর জন্য আর নোটিফিকেশন দেয় না। অ্যান্ড্রয়েড ১৫-এ সেই কনস্ট্যান্টগুলোকে আনুষ্ঠানিকভাবে ডেপ্রিকেটেড করা হয়েছে।)

  • TRIM_MEMORY_UI_HIDDEN : এই সিগন্যালটি নির্দেশ করে যে আপনার অ্যাপের UI ব্যবহারকারীর দৃষ্টির বাইরে চলে গেছে। এই পরিবর্তনটি UI-এর সাথে কঠোরভাবে যুক্ত থাকা উল্লেখযোগ্য মেমরি বরাদ্দ, যেমন বিটম্যাপ, ভিডিও প্লেব্যাক বাফার বা জটিল অ্যানিমেশন রিসোর্স, মুক্ত করার একটি সুযোগ প্রদান করে।

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

এই কোড নমুনাটি দেখায় কিভাবে বিভিন্ন মেমরি-সম্পর্কিত ইভেন্টের প্রতিক্রিয়া জানাতে একটি কম্পোজেবলে onTrimMemory কলব্যাক প্রয়োগ করতে হয়:

import android.content.ComponentCallbacks2
// Other import statements.

class MainActivity : AppCompatActivity(), ComponentCallbacks2 {

    // Other activity code.

    /**
    * Release memory when the UI becomes hidden or when system resources become low.
    * @param level the memory-related event that is raised.
    */
    override fun onTrimMemory(level: Int) {

        // The app's UI is no longer visible to the user.
        if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
            // Release memory related to UI elements.
            // Example: Clear image loading libraries' memory caches,
            // release video player buffers, or drop large custom view bitmaps.
        }

        // The app is in the background and the system is running low on memory.
        if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) {
            // Release memory related to background processing, such as by
            // closing a database connection or dropping network caches.
        }
    }
}

TRIM_MEMORY_UI_HIDDEN ইভেন্টটি নির্দেশ করে যে আপনার অ্যাপের UI ব্যবহারকারীর কাছে আর দৃশ্যমান নয়। UI লুকানো থাকার কারণে, আপনি UI-এর সাথে যুক্ত বড় রিসোর্সগুলো মুক্ত করতে পারেন, যা ব্যবহারকারী আপনার অ্যাপে ফিরে এলে সহজেই পুনর্গঠন করা যায়। এই লজিকটি আপনার ViewModel পরিবর্তে Activity বা Fragment এ রাখলে, আপনার Context ভুলবশত লিক হওয়ার কোনো সম্ভাবনা থাকে না।

যখন এমনটা ঘটে, তখন ভারী দৃশ্যমান উপাদানগুলো ছেড়ে দেওয়ার দিকে মনোযোগ দিন:

  • বিটম্যাপ ক্যাশ: ছবি প্রচুর পরিমাণে মেমরি ব্যবহার করে। আপনি যদি কোনো থার্ড-পার্টি ইমেজ লোডিং লাইব্রেরি (যেমন Coil, Glide, বা Picasso) ব্যবহার করেন, তবে সেটির নির্দিষ্ট clearMemory ফাংশনগুলো কল করুন।
  • মিডিয়া বাফার: আপনার UI-তে যদি ভিডিও বা অডিও প্লেব্যাকের ব্যবস্থা থাকে (যেমন ExoPlayer), তাহলে প্লেয়ারটি রিলিজ করুন অথবা এর মিডিয়া বাফারগুলো খালি করুন।
  • কাস্টম ভিউ ক্যাশে: আপনার যদি অত্যন্ত কাস্টমাইজড UI কম্পোনেন্ট থাকে যা জটিল অ্যানিমেশনের জন্য Bitmap বা Canvas অবজেক্ট প্রি-রেন্ডার বা ক্যাশে করে, তাহলে সেই ক্যাশেগুলো বাতিল করুন।

আপনার কতটা মেমরি প্রয়োজন তা পরীক্ষা করুন

একাধিক প্রসেস একসাথে চালানোর অনুমতি দেওয়ার জন্য, অ্যান্ড্রয়েড প্রতিটি অ্যাপের জন্য বরাদ্দ করা হিপ সাইজের উপর একটি নির্দিষ্ট সীমা নির্ধারণ করে দেয়। ডিভাইসে মোট কী পরিমাণ র‍্যাম উপলব্ধ আছে, তার উপর ভিত্তি করে হিপ সাইজের সঠিক সীমা ডিভাইসভেদে ভিন্ন হয়। যদি আপনার অ্যাপ হিপের ধারণক্ষমতায় পৌঁছে যায় এবং আরও মেমরি বরাদ্দ করার চেষ্টা করে, তাহলে সিস্টেম একটি OutOfMemoryError দেখায়।

মেমোরি শেষ হয়ে যাওয়া এড়াতে, আপনি getMemoryInfo কল করে সিস্টেমকে জিজ্ঞাসা করতে পারেন যে বর্তমান ডিভাইসে কতটা হিপ স্পেস উপলব্ধ আছে। এটি একটি ActivityManager.MemoryInfo অবজেক্ট রিটার্ন করে যা ডিভাইসের বর্তমান মেমোরির অবস্থা সম্পর্কে তথ্য প্রদান করে, যার মধ্যে রয়েছে উপলব্ধ মেমোরি, মোট মেমোরি এবং মেমোরি থ্রেশহোল্ড—অর্থাৎ সেই মেমোরি লেভেল যেখানে সিস্টেম প্রসেস বন্ধ করা শুরু করে। ActivityManager.MemoryInfo অবজেক্টটি lowMemory ও প্রকাশ করে, যা একটি বুলিয়ান ভ্যালু এবং এটি আপনাকে জানায় যে ডিভাইসে মেমোরি কম আছে কিনা।

নিম্নলিখিত কোড স্নিপেটটি দেখায় কিভাবে আপনার অ্যাপে getMemoryInfo মেথডটি ব্যবহার করতে হয়।

fun doSomethingMemoryIntensive() {

    // Before doing something that requires a lot of memory,
    // check whether the device is in a low memory state.
    if (!getAvailableMemory().lowMemory) {
        // Do memory intensive work.
    }
}

// Get a MemoryInfo object for the device's current memory status.
private fun getAvailableMemory(): ActivityManager.MemoryInfo {
    val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    return ActivityManager.MemoryInfo().also { memoryInfo ->
        activityManager.getMemoryInfo(memoryInfo)
    }
}

মনিটরের কম মেমরি মারাত্মক ক্ষতি করে

যখন সিস্টেম মেমরি অত্যন্ত কমে যায়, তখন ইউজার-ভিজিবল লো মেমরি কিল (LMK) ঘটে। মেমরি কম থাকলে, lmkd (লো মেমরি কিলার ডেমন) প্রসেসগুলোকে তাদের oom_adj_score উপর ভিত্তি করে বন্ধ করে দেয়। যে অ্যাপগুলো ক্যাশ করা থাকে, অথবা এমন কোনো সার্ভিস চালায় যার সাথে কোনো ইউজার ইন্টারফেস (UI) যুক্ত নেই (যেমন একটি জব), সেগুলোর স্কোর সবচেয়ে বেশি থাকে এবং সেগুলোকে প্রথমে বন্ধ করা হয়। যদি মেমরি অত্যন্ত কম থাকে, তাহলে ডেমনটি oom_adj_score ০ থাকা প্রসেসগুলো থেকে মেমরি পুনরুদ্ধার করতে বাধ্য হয়। যেহেতু এই স্কোরটি শুধুমাত্র দৃশ্যমান অ্যাপগুলোর জন্য সংরক্ষিত থাকে, তাই সেগুলোকে বন্ধ করার ফলে প্রসেসটি তাৎক্ষণিকভাবে এবং কোনো স্বাভাবিক প্রক্রিয়া ছাড়াই বন্ধ হয়ে যায়। ব্যবহারকারীর কাছে মনে হয় যেন অ্যাপটি ক্র্যাশ করেছে, যা প্রায়শই স্ট্যান্ডার্ড লাইফসাইকেল স্টেট-সেভিং মেকানিজমগুলোকে বাইপাস করে এবং এর ফলে ব্যবহারকারীর কাজের অগ্রগতি হারিয়ে যায়।

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

মেমরি সমস্যা ট্র্যাক করতে ProfilingManager ব্যবহার করুন

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

অ্যান্ড্রয়েড ১৭-এর সাথে চালু হওয়া দুটি ট্রিগার মেমরির সমস্যা শনাক্ত করার জন্য বিশেষভাবে উপযোগী:

  • TRIGGER_TYPE_OOM নির্দেশ করে যে অ্যাপটি একটি OutOfMemoryError থ্রো করেছে। ক্র্যাশের পর অ্যাপটি পরবর্তীবার চালু হওয়ার সময়, যখন অ্যাপটি প্রোফাইলিং ট্রিগারের জন্য রেজিস্টার করে, তখন এটি ট্রিগার হয়।
  • যখন সিস্টেম অ্যাপটির কোনো অস্বাভাবিক আচরণ শনাক্ত করে, তখন TRIGGER_TYPE_ANOMALY ট্রিগার হয়। অন্যান্য কারণের মধ্যে, অতিরিক্ত মেমরি ব্যবহারের কারণেও এটি ট্রিগার হতে পারে। অ্যাপটি অতিরিক্ত মেমরি ব্যবহার করার পর এবং সমস্যা সৃষ্টিকারী প্রসেসটিকে বন্ধ করার জন্য সিস্টেম কোনো পদক্ষেপ নেওয়ার আগেই এটি ট্রিগার হয়। উদাহরণস্বরূপ, যদি অ্যাপটি অ্যান্ড্রয়েড ১৭-এ প্রবর্তিত মেমরি সীমা অতিক্রম করে, তাহলে সিস্টেম অ্যাপটিকে বন্ধ করার আগেই TRIGGER_TYPE_ANOMALY ট্রিগার হয়।

প্রোগ্রাম্যাটিকভাবে ট্রিগার রেজিস্টার এবং পুনরুদ্ধার করতে ProfilingManager ব্যবহারের বিষয়ে আরও তথ্যের জন্য, ট্রিগার-ভিত্তিক প্রোফাইলিং ডকুমেন্টেশন দেখুন। Firebase Crashlytics এছাড়াও TRIGGER_TYPE_OOM এবং TRIGGER_TYPE_ANOMALY উভয় ট্রিগারকে সমর্থন করে এবং সেগুলোকে অন্যান্য ডায়াগনস্টিক মেটাডেটার সাথে সম্পর্কযুক্ত করে।

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

প্রক্রিয়ার অবস্থা এবং মেমরি ট্র্যাক করুন

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

ক্রমাগত পর্যবেক্ষণের জন্য একটি পাইথন ড্যাশবোর্ড সহ

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

python3 android_mem_monitor.py your.package.name

ড্যাশবোর্ডের বৈশিষ্ট্য ও ব্যবহার সম্পর্কে বিস্তারিত নির্দেশাবলীর জন্য README ফাইল অথবা স্ক্রিপ্টের ইনলাইন কমেন্টগুলো দেখুন।

রানটাইমে ActivityManager সাথে

রানটাইমে আপনার চলমান প্রসেসগুলো সম্পর্কে তথ্য পেতে, আপনি ActivityManager.getRunningAppProcesses কোয়েরি করতে পারেন। এটি আপনার অ্যাপের প্রতিটি প্রসেস সম্পর্কে প্রাথমিক তথ্য সম্বলিত অবজেক্টের একটি তালিকা ফেরত দেয়। importance ফিল্ডটি প্রসেসটির উপর সিস্টেমের দেওয়া আপেক্ষিক গুরুত্ব নির্দেশ করে এবং এটি নিম্নলিখিত কনস্ট্যান্টগুলোর সাথে ম্যাপ করা থাকে:

  • IMPORTANCE_FOREGROUND : প্রসেসটি সক্রিয়ভাবে ফোরগ্রাউন্ড UI চালাচ্ছে।
  • IMPORTANCE_FOREGROUND_SERVICE : প্রসেসটি একটি ফোরগ্রাউন্ড সার্ভিস চালাচ্ছে (যেমন সক্রিয় ব্যাকগ্রাউন্ড মিউজিক বা বড় আকারের ডাউনলোড), যা একটি ইউজার-পারসিভড সার্ভিসের উদাহরণ।
  • IMPORTANCE_CACHED : এই প্রসেসটিতে ক্যাশ করা কোড রয়েছে। প্রসেসটি স্থির হয়ে যায় এবং এর অব্যবহৃত মেমরি অ্যান্ড্রয়েড দ্বারা পুনরুদ্ধার করা হয়। এই অবস্থায়, ওএস MemoryLimiter তার অ্যাপ-নির্দিষ্ট মেমরি সীমা অতিক্রম করার জন্য অ্যাপটি বন্ধ করে দেবে না। তবে, যদি পুরো সিস্টেমে মেমরি কম থাকে, তাহলে অ্যাপটি লো-মেমোরি কিলারের প্রধান শিকার হতে পারে।

adb দিয়ে ডিবাগ করার জন্য

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

  • সক্রিয় প্রসেস আইডি (PID) খুঁজুন: প্রথমে, আপনার প্যাকেজ নেম দিয়ে ফিল্টার করে ps কমান্ড ব্যবহার করে আপনার অ্যাপে বর্তমানে চলমান সমস্ত প্রসেস খুঁজে বের করুন।
    shell adb shell ps -A | grep your.package.name
  • বর্তমান OOM স্কোর পরীক্ষা করুন: একটি প্রসেসের PID ব্যবহার করে প্রসেস ফাইল সিস্টেম থেকে এর OOM স্কোর পড়ুন। সাধারণত ০-১৯৯ স্কোর একটি ফোরগ্রাউন্ডেড অ্যাপ নির্দেশ করে, ২০০-২৪৯ একটি দৃশ্যমান সার্ভিসকে বোঝায়, ২৫০-৮৯৯ একটি ব্যাকগ্রাউন্ড সার্ভিসের জন্য এবং ৯০০+ স্কোরের অর্থ হলো প্রসেসটি ক্যাশড এবং সম্ভবত কিল করা হবে।
    shell adb shell cat /proc/ pid /oom_score_adj
  • OOM স্কোর ক্রমাগত নিরীক্ষণ করুন: একটি অ্যাপের OOM স্কোরের (যা হবে এর সমস্ত প্রসেসের মধ্যে সর্বনিম্ন OOM স্কোর) পরিবর্তন ক্রমাগত নিরীক্ষণ করতে, আপনি watch-uids কমান্ডটি ব্যবহার করতে পারেন।
    shell adb shell am watch-uids
  • মেমরি ফুটপ্রিন্ট পরিমাপ করুন: কোনো প্রসেসের কোর মেমরি ফুটপ্রিন্ট, যেমন অ্যানোনিমাস আরএসএস (Anonymous RSS) এবং সোয়াপ (Swap) মেমরি ব্যবহারের পরিমাণ , দ্রুত জানার জন্য সরাসরি লিনাক্স প্রসেস ফাইল সিস্টেম থেকে এর স্ট্যাটাস পড়ুন।
    shell adb shell cat /proc/ pid /status | grep -E "VmRSS|RssAnon|VmSwap"
    মেমরি বরাদ্দের আরও বিস্তারিত ও বিশদ বিশ্লেষণের জন্য, dumpsys meminfo কমান্ডটি ব্যবহার করুন:
    shell adb shell dumpsys meminfo pid
  • সক্রিয় উপাদানগুলো তদন্ত করুন: যদি আপনার প্রসেসটি অপ্রত্যাশিতভাবে উচ্চ প্রায়োরিটি বজায় রাখে (যেমন ক্যাশেড-এ নেমে যাওয়ার পরিবর্তে OOM স্কোর 200 তে থেকে যায়), তাহলে প্রসেসটি ঠিক কী চালাচ্ছে তা আপনি খতিয়ে দেখতে পারেন। ` dumpsys activity processes কমান্ডটি সেই নির্দিষ্ট অ্যাক্টিভিটি, সার্ভিস, প্রোভাইডার এবং রিসিভারগুলো প্রকাশ করে, যেগুলো প্রসেসটিকে সচল রাখছে।
    shell adb shell dumpsys activity processes your.package.name

আরও মেমরি-সাশ্রয়ী কোড কাঠামো ব্যবহার করুন

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

পরিষেবাগুলি মিতব্যয়ীভাবে ব্যবহার করুন

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

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

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

অপ্টিমাইজ করা ডেটা কন্টেইনার ব্যবহার করুন

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

অ্যান্ড্রয়েড ফ্রেমওয়ার্কে SparseArray , SparseBooleanArray , এবং LongSparseArray সহ বেশ কিছু অপ্টিমাইজ করা ডেটা কন্টেইনার রয়েছে। উদাহরণস্বরূপ, SparseArray ক্লাসগুলো আরও বেশি কার্যকর, কারণ এগুলো সিস্টেমের key এবং কখনও কখনও value-কে অটোবক্স করার প্রয়োজনীয়তা এড়িয়ে চলে, যা প্রতিটি এন্ট্রির জন্য আরও এক বা দুটি অবজেক্ট তৈরি করে।

প্রয়োজনে, একটি সংক্ষিপ্ত ডেটা কাঠামোর জন্য আপনি র অ্যারে ব্যবহার করতে পারেন।

কোড অ্যাবস্ট্রাকশন নিয়ে সতর্ক থাকুন

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

সিরিয়ালাইজড ডেটার জন্য লাইট প্রোটোবাফ ব্যবহার করুন

প্রোটোকল বাফার (প্রোটোবাফ) হলো গুগল দ্বারা ডিজাইন করা একটি ভাষা-নিরপেক্ষ, প্ল্যাটফর্ম-নিরপেক্ষ এবং সম্প্রসারণযোগ্য প্রক্রিয়া, যা স্ট্রাকচার্ড ডেটা সিরিয়ালাইজ করার জন্য ব্যবহৃত হয়। এটি XML বা JSON-এর মতো, কিন্তু আকারে ছোট, দ্রুত এবং সরল। আপনি যদি আপনার ডেটার জন্য প্রোটোবাফ ব্যবহার করেন, তবে আপনার ক্লায়েন্ট-সাইড কোডে সর্বদা লাইট প্রোটোবাফ ব্যবহার করুন। সাধারণ প্রোটোবাফ অত্যন্ত বিশদ কোড তৈরি করে, যা র‍্যামে আপনার অ্যাপের কোড ফুটপ্রিন্ট বাড়িয়ে দেয় (দেখুন: আপনার অ্যাপের কোড এবং রিসোর্স ফুটপ্রিন্ট কমান ) এবং APK ফাইলের আকার বৃদ্ধিতে ভূমিকা রাখে।

আরও তথ্যের জন্য, প্রোটোবাফ রিডমি দেখুন।

মেমরি লিক সম্পর্কে সতর্ক থাকুন

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

স্মৃতিশক্তির জঞ্জাল এড়িয়ে চলুন

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

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

উদাহরণস্বরূপ, আপনি একটি for লুপের মধ্যে একাধিক অস্থায়ী অবজেক্ট বরাদ্দ করতে পারেন। অথবা, আপনি একটি কম্পোজেবলের রিকম্পোজিশনের সময় বা একটি DrawScope কলের (যেমন Canvas ) ভিতরে Brush , Path , বা ডেটা ফরম্যাটিং অবজেক্ট ইনস্ট্যানশিয়েট করতে পারেন। উভয় ক্ষেত্রেই, অ্যাপটি দ্রুত প্রচুর অবজেক্ট তৈরি করে। এগুলি ইয়ং জেনারেশনে উপলব্ধ সমস্ত মেমরি দ্রুত ব্যবহার করে ফেলতে পারে, যার ফলে একটি গার্বেজ কালেকশন ইভেন্ট ঘটতে বাধ্য হয়।

আপনার কোডের যে জায়গাগুলোতে মেমরি ব্যবহার বেশি, সেগুলো খুঁজে বের করতে মেমরি প্রোফাইলার ব্যবহার করুন, যাতে আপনি সেগুলো ঠিক করতে পারেন।

আপনার কোডের সমস্যাযুক্ত জায়গাগুলো চিহ্নিত করার পর, পারফরম্যান্সের জন্য গুরুত্বপূর্ণ অংশগুলোতে মেমোরি অ্যালোকেশনের সংখ্যা কমানোর চেষ্টা করুন। ভেতরের লুপ থেকে মেমোরিগুলো বের করে আনার কথা ভাবতে পারেন, অথবা সেগুলোকে ফ্যাক্টরি-ভিত্তিক অ্যালোকেশন কাঠামোতে স্থানান্তর করতে পারেন।

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

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

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