অ্যান্ড্রয়েড ১১ (এপিআই লেভেল ৩০) বা তার উচ্চতর সংস্করণ ক্যাশড অ্যাপস ফ্রিজার ফিচারটি সমর্থন করে। এই ফিচারটি ক্যাশড প্রসেসগুলোর এক্সিকিউশন বন্ধ করে দেয় এবং ক্যাশড অবস্থায় চলতে চেষ্টা করতে পারে এমন অনাকাঙ্ক্ষিত অ্যাপগুলোর রিসোর্স ব্যবহার কমিয়ে দেয়।
ক্যাশড অ্যাপস ফ্রিজার অ্যাপগুলোকে সিপিইউ থেকে দূরে রেখে র্যামে রাখে। অ্যান্ড্রয়েড যখন মনে করে যে কোনো অ্যাপের এখন কাজ করা উচিত নয়, কিন্তু ভবিষ্যতে এটির প্রয়োজন হতে পারে, তখন এটি অ্যাপ প্রসেসটিকে বন্ধ না করে ফ্রিজ করে দেয়। এর ফলে, অ্যাপটির আবার প্রয়োজন হলে এটি কোল্ড স্টার্ট হওয়া থেকে বিরত থাকে।
অ্যান্ড্রয়েড ক্যাশ করা অ্যাপগুলোর প্রসেসগুলোকে একটি ফ্রোজেন সি-গ্রুপে স্থানান্তরিত করে সেগুলোকে ফ্রিজ করে দেয়। এর ফলে, সক্রিয় ক্যাশ করা অ্যাপ থাকলে সক্রিয় এবং নিষ্ক্রিয় সিপিইউ-এর ব্যবহার কমে যায়। আপনি একটি সিস্টেম কনফিগারেশন ফ্ল্যাগ অথবা একটি ডেভেলপার অপশন ব্যবহার করে অ্যাপ ফ্রিজারটি চালু করতে পারেন।
অ্যান্ড্রয়েড ১৪ (এপিআই লেভেল ৩৪) এবং এর পরবর্তী সংস্করণগুলোতে, ক্যাশড অ্যাপস ফ্রিজারটিতে নিম্নলিখিত শক্তিশালী বৈশিষ্ট্যগুলো অন্তর্ভুক্ত রয়েছে:
- ক্যাশড অবস্থায় থাকা অ্যাপ প্রসেসগুলো ক্যাশড অবস্থায় প্রবেশ করার ১০ সেকেন্ড পর স্থির হয়ে যায়।
- সিস্টেমটি কোনো লাইফসাইকেল ইভেন্টের সময় একটি ফ্রিজ হয়ে যাওয়া অ্যাপ প্রসেসকে তাৎক্ষণিকভাবে আনফ্রিজ করে। এই ইভেন্টগুলোর মধ্যে রয়েছে একটি ইন্টেন্ট গ্রহণ করা, একটি জব সার্ভিস চালু করা, অথবা ব্যবহারকারীর কোনো অ্যাক্টিভিটি পুনরায় শুরু করা।
ActivityManagerService অ্যাপের সমস্ত প্রসেস পরিচালনা করে এবং অ্যাপের জীবনচক্র সংক্রান্ত সিদ্ধান্ত গ্রহণ করে। CachedAppOptimizer অ্যাপ প্রসেসকে স্থির বা ফ্রিজ করার জন্য দায়ী।
যখন কোনো অ্যাপ প্রসেস ফ্রিজ হয়ে যায়, তখন এর সমস্ত থ্রেড স্থগিত হয়ে যায় এবং আনফ্রিজ না হওয়া পর্যন্ত সিপিইউ-এর কোনো কাজ করতে পারে না। এর ফলে, অ্যাপটি গার্বেজ কালেকশন (GC) করতে পারে না এবং মেমরি ট্রিম ইভেন্টে সাড়া দিতে পারে না। বিস্তারিত জানতে, ComponentCallbacks2.onTrimMemory(int) দেখুন। এই সমস্যার সমাধানের জন্য, অ্যান্ড্রয়েড ১৪ থেকে শুরু করে:
- যেসব অ্যাপের একটি দৃশ্যমান
Activityইনস্ট্যান্স থাকে, সেগুলো ব্যাকগ্রাউন্ডে যাওয়ার সাথে সাথেইTRIM_MEMORY_UI_HIDDENইভেন্টের নোটিফিকেশন পায়। যেসব অ্যাপ UI ছাড়া লাইফসাইকেলে থাকে, যেমন ফোরগ্রাউন্ড সার্ভিসযুক্ত অ্যাপ, সেগুলোTRIM_MEMORY_BACKGROUNDপেতে পারে। অন্যান্য ট্রিম ইভেন্টগুলো ডেলিভার করা হয় না, কারণ যখন অ্যাপগুলো সেই ইভেন্টগুলোর জন্য যোগ্য হয়, তখন সেগুলোকে ফ্রিজড বা স্থির থাকার কথা। - ক্যাশড অবস্থায় প্রবেশ করার কিছুক্ষণ পরেই, সম্ভাব্য ফ্রিজ হয়ে যাওয়ার প্রস্তুতির অংশ হিসেবে সিস্টেমটি অ্যাপ রানটাইমকে একটি GC (গার্বেজ কালেকশন) সম্পাদন করার জন্য অনুরোধ করতে পারে।
- যখন কোনো অ্যাপ প্রসেস ফ্রিজ হয়ে যায়, তখন অতিরিক্ত মেমরি কম্প্যাকশন ধাপ সংঘটিত হতে পারে, যেমন ডার্টি পেজগুলোকে ব্যাকিং স্টোরেজে লেখা এবং অ্যানোনিমাস পেজগুলোকে ZRAM-এ সোয়াপ করা।
- যদি কোনো নির্দিষ্ট অ্যাপের সমস্ত প্রসেস ফ্রিজ হয়ে যায়, তাহলে সিস্টেম অ্যাপটি দ্বারা পরিচালিত যেকোনো সক্রিয় TCP সকেট বন্ধ করে দেয়। এর ফলে সকেটের সার্ভার প্রান্ত থেকে এমন TCP কিপঅ্যালাইভ পিং পাঠানো যায় না, যা ডিভাইসের মডেমকে জাগিয়ে তুলতে পারে।
ক্যাশ করা অ্যাপ প্রসেসগুলো আনফ্রিজ করা হয় যখন তাদের প্রসেস স্টেট 'ক্যাশড' অবস্থা থেকে আরও গুরুত্বপূর্ণ কোনো অবস্থায় উন্নীত হয়। অ্যান্ড্রয়েড ১৪ এবং তার পরবর্তী সংস্করণগুলোতে আনফ্রিজ ইভেন্টের সংখ্যা কমাতে, অ্যাপটি ক্যাশড অবস্থায় থাকাকালীন সিস্টেম 'কন্টেক্সট-রেজিস্টার্ড' ব্রডকাস্টগুলোকে কিউতে রাখে। কন্টেক্সট-রেজিস্টার্ড ব্রডকাস্ট হলো এমন রিসিভার যা একটি অ্যাপ Context.registerReceiver ' কল করে ডাইনামিকভাবে রেজিস্টার করে। অ্যাপটি আনফ্রিজ হওয়ার পরেই সিস্টেম এই কিউতে থাকা ব্রডকাস্টগুলো ডেলিভার করে। এর বিপরীতে, সিস্টেম 'ম্যানিফেস্ট-ডিক্লেয়ার্ড' ব্রডকাস্টগুলোকে কিউতে রাখে না। 'ম্যানিফেস্ট-ডিক্লেয়ার্ড' ব্রডকাস্ট হলো এমন রিসিভার যা AndroidManifest.xml এ <receiver> ' এলিমেন্ট ব্যবহার করে স্ট্যাটিক্যালি ডিক্লেয়ার করা হয়। 'ম্যানিফেস্ট-ডিক্লেয়ার্ড' ব্রডকাস্টগুলো ডেলিভার করার জন্য সিস্টেম তাৎক্ষণিকভাবে ক্যাশ করা অ্যাপটিকে আনফ্রিজ করে।
সিস্টেমের স্বাস্থ্যগত প্রভাব
যদি MAX_CACHED_PROCESSES এর চেয়ে বেশি ক্যাশড অ্যাপ প্রসেস থাকে, তাহলে অ্যান্ড্রয়েড সবচেয়ে কম ব্যবহৃত ক্যাশড অ্যাপ প্রসেসটিকে বন্ধ করে দেয়। অ্যান্ড্রয়েড ১৪ বা তার উচ্চতর সংস্করণে চালিত সমর্থিত ডিভাইসগুলিতে, MAX_CACHED_PROCESSES উল্লেখযোগ্যভাবে বাড়ানো হয়েছে, যা ডিভাইসগুলিকে র্যামে যথেষ্ট বেশি ক্যাশড অ্যাপ প্রসেস বজায় রাখতে সক্ষম করে।
র্যামে আরও বেশি অ্যাপ ক্যাশ করে রাখলে কোল্ড স্টার্টের সময় ৩০% পর্যন্ত কমে যায়, এবং এই হ্রাসের পরিমাণ ডিভাইসের মোট র্যামের উপর নির্ভর করে। একই সাথে, ক্যাশ করা অ্যাপগুলোর সিপিইউ ব্যবহারও কমে যায়, যার ফলে উল্লেখযোগ্য পরিমাণে ব্যাটারি সাশ্রয় হয়।
ফ্রিজার ছাড়
নির্দিষ্ট কিছু পরিস্থিতিতে, একটি অ্যাপ প্রসেস ক্যাশড অবস্থায় প্রবেশ করলেও আনফ্রিজড থাকতে পারে। এই ব্যতিক্রমগুলো হলো বাস্তবায়নগত খুঁটিনাটি বিষয় এবং ভবিষ্যতের অ্যান্ড্রয়েড সংস্করণগুলোতে এগুলো পরিবর্তিত হতে পারে:
- ফাইল লক: যদি কোনো ক্যাশড প্রসেস এমন একটি ফাইল লক ধরে রাখে যা অন্য নন-ক্যাশড প্রসেসগুলোকে ব্লক করে, তবে লকটি ধরে থাকা প্রসেসটি ফ্রিজ হয় না।
-
BIND_WAIVE_PRIORITYবাইন্ডিং:Context.BIND_WAIVE_PRIORITYব্যবহার করে তৈরি ইনকামিং বাইন্ডিং সহ অ্যাপ প্রসেসগুলি ক্যাশড অবস্থায় প্রবেশ করতে পারে, কিন্তু সমস্ত সংযুক্ত ক্লায়েন্ট প্রসেসও ক্যাশড না হওয়া পর্যন্ত আনফ্রোজেন থাকে। এই ছাড়টি মাল্টি-প্রসেস অ্যাপগুলিকে সমর্থন করে, যেমন কাস্টম ট্যাব ব্যবহারকারী ওয়েব ব্রাউজার।
অ্যাপস ফ্রিজার বাস্তবায়ন করুন
ক্যাশড অ্যাপস ফ্রিজারটি কার্নেল সিগ্রুপ ভি২ ফ্রিজার ব্যবহার করে। সামঞ্জস্যপূর্ণ কার্নেলসহ ডিভাইসগুলো এটি সক্রিয় করতে পারে। ডেভেলপার অপশন ‘Suspend execution for cached apps’ সক্রিয় করুন অথবা ডিভাইস কনফিগ ফ্ল্যাগ ‘ activity_manager_native_boot use_freezer ‘ true সেট করুন। উদাহরণস্বরূপ:
adb shell device_config put activity_manager_native_boot use_freezer true && adb reboot যখন আপনি use_freezer ফ্ল্যাগটিকে false সেট করেন অথবা ডেভেলপার অপশনটি নিষ্ক্রিয় করেন, তখন ফ্রিজারটি নিষ্ক্রিয় হয়ে যায়। উদাহরণস্বরূপ:
adb shell device_config put activity_manager_native_boot use_freezer false && adb rebootসফটওয়্যার রিলিজ বা আপডেটে ডিভাইসের কনফিগারেশন পরিবর্তন করে আপনি এই সেটিংটি চালু বা বন্ধ করতে পারেন।
MAX_CACHED_PROCESSES ওভাররাইড করতে, উদাহরণস্বরূপ, পরীক্ষার জন্য এর মান 1024-এ সেট করতে:
adb shell device_config put activity_manager max_cached_processes 1024
adb shell device_config set_sync_disabled_for_tests persistent MAX_CACHED_PROCESSES ওভাররাইডটি পূর্বাবস্থায় ফিরিয়ে আনতে:
adb shell device_config delete activity_manager max_cached_processes
adb shell device_config set_sync_disabled_for_tests none অ্যাপস ফ্রিজারটি কোনো অফিশিয়াল এপিআই প্রকাশ করে না এবং এর কোনো রেফারেন্স ইমপ্লিমেন্টেশন ক্লায়েন্টও নেই, কিন্তু এটি একটি নির্দিষ্ট প্রসেস ফ্রিজ করার জন্য setProcessFrozen এবং বিশ্বব্যাপী ফ্রিজিং চালু বা বন্ধ করার জন্য enableFreezer নামক হিডেন সিস্টেম এপিআই ব্যবহার করে।
কাস্টম বৈশিষ্ট্যগুলি পরিচালনা করুন
ক্যাশড থাকা অবস্থায় অ্যাপ প্রসেসগুলোর কোনো কাজ করার কথা নয়, কিন্তু কিছু অ্যাপে এমন কাস্টম ফিচার থাকতে পারে যা এমন প্রসেস দ্বারা সমর্থিত হয়, যেগুলো ক্যাশড থাকা অবস্থায় চলার কথা। যখন এই ধরনের অ্যাপ চালিত কোনো ডিভাইসে অ্যাপস ফ্রিজার চালু করা হয়, তখন ক্যাশড প্রসেসগুলো ফ্রিজ হয়ে যায় এবং এর ফলে কাস্টম ফিচারগুলো কাজ করতে বাধা পেতে পারে।
একটি বিকল্প সমাধান হিসেবে, প্রসেসটি কোনো কাজ করার আগেই আপনি এর স্ট্যাটাস পরিবর্তন করে 'ননক্যাশড' করে দিতে পারেন। এই পরিবর্তনের ফলে অ্যাপগুলো সক্রিয় থাকতে পারে। সক্রিয় স্ট্যাটাসের উদাহরণগুলোর মধ্যে রয়েছে একটি বাউন্ড ফোরগ্রাউন্ড সার্ভিস বা ফোরগ্রাউন্ড স্ট্যাটাস।
সাধারণ ব্যর্থতার ধরণগুলি
যখন অ্যাপ প্রসেসগুলো স্থবির হয়ে যায়, তখন ত্রুটিপূর্ণ আন্তঃ-প্রসেস যোগাযোগ (IPC) বা টাস্ক শিডিউলিংয়ের কারণে অ্যাপটি বন্ধ হয়ে যেতে পারে বা অপ্রত্যাশিত আচরণ করতে পারে।
হিমায়িত প্রক্রিয়াগুলিতে সিঙ্ক্রোনাস বাইন্ডার লেনদেন
যখন কোনো ক্লায়েন্ট অ্যাপ প্রসেস একটি ফ্রোজেন (frozen) সার্ভার অ্যাপ প্রসেসে একটি সিনক্রোনাস বাইন্ডার ট্রানজ্যাকশন পাঠায়, তখন সিস্টেম অবিলম্বে সার্ভার অ্যাপ প্রসেসটিকে টার্মিনেট করে দেয়। এর ফলে ফ্রোজেন সার্ভার থেকে প্রতিক্রিয়ার জন্য অপেক্ষা করার সময় ক্লায়েন্ট থ্রেডটি অনির্দিষ্টকালের জন্য ব্লক হয়ে যায় না। এরপর ক্লায়েন্ট থ্রেডটি RemoteException গ্রহণ করে এবং যেকোনো রেজিস্টার্ড লিসেনার ট্রিগার হয়। বিস্তারিত জানতে, IBinder.linkToDeath দেখুন।
মূল কারণ: এই ব্যর্থতা সাধারণত ক্লায়েন্ট অ্যাপের কোনো বাগের কারণে ঘটে থাকে। যখন কোনো ক্লায়েন্ট একটি সার্ভিসের সাথে বাইন্ড করে, তখন সার্ভার প্রসেসটি ক্লায়েন্টের সাথে বাইন্ড হয়ে যায় এবং ক্লায়েন্টের আগে ক্যাশড স্টেটে প্রবেশ করতে বাধা পায়। বিস্তারিত জানতে Context.bindService দেখুন। তবে, ক্লায়েন্ট যখন Context.unbindService কল করে, তখন সার্ভার প্রসেসটি ক্যাশড এবং ফ্রোজেন হয়ে যেতে পারে। আনবাইন্ডিংয়ের পরেও যদি ক্লায়েন্ট ক্যাশড IBinder রেফারেন্সটি ব্যবহার করতে থাকে, তবে এটি একটি ফ্রোজেন প্রসেসের সাথে যোগাযোগের ঝুঁকি তৈরি করে।
এই সমস্যা এড়াতে, নিশ্চিত করুন যে ক্লায়েন্ট অ্যাপগুলো Context.unbindService কল করার সাথে সাথেই IBinder রেফারেন্সগুলো বাতিল করে দেয়।
অ্যাসিঙ্ক্রোনাস বাইন্ডার ট্রানজ্যাকশন বাফার ওভারফ্লো
যখন কোনো সার্ভার অ্যাপ প্রসেস ফ্রোজেন (frozen) অবস্থায় অ্যাসিঙ্ক্রোনাস ( oneway ) বাইন্ডার ট্রানজ্যাকশন গ্রহণ করে, তখন ট্রানজ্যাকশনগুলো প্রতিটি প্রসেসের জন্য একটি বাফারে জমা হয়। ফ্রোজেন অবস্থায় সার্ভার যদি অতিরিক্ত অ্যাসিঙ্ক্রোনাস ট্রানজ্যাকশন গ্রহণ করে, তাহলে বাফারটি ওভারফ্লো হয়ে যায় এবং সিস্টেম সার্ভার অ্যাপ প্রসেসটিকে বন্ধ করে দেয়।
এই বাফার ওভারফ্লো প্রতিরোধ করতে, ক্যাশড বা ফ্রোজেন থাকতে পারে এমন প্রসেসগুলিতে অতিরিক্ত অ্যাসিঙ্ক্রোনাস বাইন্ডার ট্রানজ্যাকশন পাঠানো থেকে বিরত থাকুন।
আনফ্রিজ করার পর নির্ধারিত কাজগুলোর পুনরাবৃত্তিমূলক সম্পাদন।
যদি কোনো অ্যাপ পুনরাবৃত্তিমূলক কাজ সম্পাদন করে, তাহলে প্রসেসটি ফ্রিজ থাকা অবস্থায় সেই কাজগুলো স্থগিত হয়ে যায়। বিস্তারিত জানতে ScheduledThreadPoolExecutor.scheduleAtFixedRate অথবা Timer.scheduleAtFixedRate দেখুন। প্রসেসটি আনফ্রিজ হলে, জমে থাকা বাদ পড়া এক্সিকিউশনগুলো কার্যত কোনো বিলম্ব ছাড়াই দ্রুত একের পর এক চলতে পারে।
অ্যাপটি আনফ্রিজ হওয়ার সময় যাতে হঠাৎ করে অনেক বেশি টাস্ক চালু না হয়ে যায়, সেজন্য ব্যাকগ্রাউন্ড টাস্কের ক্ষেত্রে scheduleAtFixedRate এর পরিবর্তে scheduleWithFixedDelay ব্যবহার করুন। এছাড়া আপনি WorkManager ও ব্যবহার করতে পারেন।
অ্যাপস ফ্রিজার পরীক্ষা ও সমস্যা সমাধান করুন
অ্যাপ ফ্রিজারটি উদ্দেশ্য অনুযায়ী কাজ করছে কিনা তা যাচাই করতে অথবা ফ্রিজার-সম্পর্কিত সমস্যা সমাধান করতে, নিম্নলিখিত ডায়াগনস্টিক টুল এবং কমান্ডগুলি ব্যবহার করুন:
কার্যকলাপ ব্যবস্থাপক কমান্ড
আপনি adb shell am কমান্ড ব্যবহার করে কোনো নির্দিষ্ট প্রসেসের জন্য ফ্রিজিং এবং কম্প্যাকশন ম্যানুয়ালি নিয়ন্ত্রণ করতে পারেন:
একটি প্রক্রিয়াকে জোর করে থামিয়ে দিন:
adb shell am freeze <process>একটি প্রক্রিয়াকে জোর করে আনফ্রিজ করা:
adb shell am unfreeze <process>কোনো প্রসেসের উপর সম্পূর্ণ মেমরি কম্প্যাকশন জোর করে প্রয়োগ করা:
adb shell am compact full <process>
লগক্যাট পরীক্ষা
প্রতিবার কোনো প্রসেস ফ্রিজারে প্রবেশ করলে বা ফ্রিজার থেকে বেরিয়ে গেলে, ফ্রোজেন এবং আনফ্রোজেন এন্ট্রিগুলো দেখতে লগক্যাট দেখুন:
adb logcat | grep -i "\(freezing\|froze\)" আনফ্রিজ কারণ লগ আউটপুটে UnfreezeReason প্রোটোকল বাফার enum থেকে গণনাকৃত মানসমূহ পাওয়া যায়।
ডাম্পসি পরিদর্শন
dumpsys activity ব্যবহার করে হিমায়িত প্রসেসগুলির তালিকা পরীক্ষা করুন:
adb shell dumpsys activity | grep -A 20 "Apps frozen:"/sys/fs/cgroup/uid_0/cgroup.freeze ফাইলটির উপস্থিতি যাচাই করুন।
অ্যাপ্লিকেশন প্রস্থান তথ্য
পূর্ববর্তী কোনো প্রসেস বন্ধ হওয়ার কারণ জানতে, ActivityManager.getHistoricalProcessExitReasons দেখুন। যদি কোনো অ্যাপ প্রসেস ফ্রিজার-সম্পর্কিত কোনো সমস্যার কারণে বন্ধ হয়ে যায়, যেমন ফ্রোজেন থাকা অবস্থায় একটি সিনক্রোনাস বাইন্ডার ট্রানজ্যাকশন গ্রহণ করা, তাহলে বন্ধ হওয়ার কারণটি ApplicationExitInfo.REASON_FREEZER এ সেট করা হয়।
পারফেট্টো ট্রেসিং
Perfetto ট্রেসে system_server প্রসেসের অধীনে Freezer নামের একটি ট্র্যাকে ফ্রিজার-সম্পর্কিত ইভেন্টগুলি নির্গত হয়:
-
FreezeএবংUnfreezeস্লাইসগুলো নির্দেশ করে কখন একটি প্রসেস তার অবস্থা পরিবর্তন করে। -
updateAppFreezeStateLSPইভেন্টগুলো দেখায় কখন সিস্টেম সার্ভার কোনো প্রসেসকে ফ্রিজ বা আনফ্রিজ করার সিদ্ধান্ত নিতে তার অ্যাট্রিবিউটগুলো পুনরায় পরীক্ষা করে।
আপনি এই ইভেন্টগুলি সরাসরি পারফেটটো UI-তে পরিদর্শন করতে পারেন অথবা পারফেটটোএসকিউএল (PerfettoSQL) ব্যবহার করে বিশ্লেষণ করতে পারেন:
INCLUDE PERFETTO MODULE slices.with_context;
SELECT *
FROM process_slice
WHERE process_name = "system_server"
AND track_name = "Freezer"
AND (name LIKE "Freeze %" OR name LIKE "Unfreeze %");
PerfettoSQL স্ট্যান্ডার্ড লাইব্রেরিতে, ফ্রিজার ইভেন্টগুলো android_freezer_events টেবিলেও সংক্ষিপ্ত আকারে তালিকাভুক্ত করা হয়।