Android-এ অ্যাপ প্রসেস আইসোলেশনে থাকে না। অ্যাপ্লিকেশন প্রায়ই অন্যান্য অ্যাপ্লিকেশন বা সিস্টেমের প্রদান করা পরিষেবার উপর নির্ভর করে। একটি প্রসেস যখন সার্ভিস বাইন্ডিং-এর মাধ্যমে অন্যটির সাথে কানেক্ট করে, তখন এটি একটি ডিপেন্ডেন্সি তৈরি করে যা Android ফ্রেমওয়ার্ক কীভাবে মেমরি ম্যানেজ করে তার উপর গভীর প্রভাব ফেলে।
প্রসেস স্টেট ও OOM স্কোর
Android ফ্রেমওয়ার্ক প্রসেস স্টেট ব্যবহার করে প্রতিটি
চলমান প্রসেসের গুরুত্ব ট্র্যাক করে। এইসব স্টেট তারপর OomAdjuster-এর মাধ্যমে ব্যবহার করা হয় যাতে
OOM স্কোর অ্যাডজাস্টমেন্ট (oom_score_adj) ভ্যালু অ্যাসাইন করা যায়, যার রেঞ্জ হল -১০০০ থেকে ১০০০।
oom_score_adj-এর মান কম হলে, প্রসেসটি আরও গুরুত্বপূর্ণ এবং লো মেমরি কিলার (LMK) দ্বারা
বন্ধ হওয়ার সম্ভাবনা কম।
সাধারণ প্রসেস স্টেট
নিচের সারণীতে সবচেয়ে সাধারণ কিছু প্রসেস স্টেট এবং সেগুলির
সাধারণ oom_score_adj ভ্যালু দেখানো হয়েছে। সম্পূর্ণ ও আপ-টু-ডেট তালিকার জন্য, Android সোর্স কোডে android.app.ActivityManager ও com.android.server.am.psc.Constants
দেখুন।
| প্রসেস স্টেট (সংক্ষিপ্ত) | বর্ণনা | স্বাভাবিক oom_score_adj |
|---|---|---|
| PER (স্থায়ী) | সিস্টেম প্রসেস যা সবসময় চালু রাখতে হবে (যেমন, টেলিফোনি)। | -800 |
| সেরা | ব্যবহারকারী বর্তমানে যে প্রসেসের সাথে ইন্টার্যাক্ট করছেন। | 0 |
| VIS (দৃশ্যমান) | প্রসেসটিতে একটি দৃশ্যমান অ্যাক্টিভিটি আছে (যেমন, একটি ট্রান্সলুসেন্ট ডায়ালগের পিছনে)। | 100 |
| PERC (অনুভবযোগ্য) | ব্যবহারকারী ব্যাকগ্রাউন্ড প্রসেস সম্পর্কে জানেন (যেমন, মিউজিক প্লেব্যাক)। | 200 |
| FGS | ফোরগ্রাউন্ড সার্ভিস হোস্ট করার প্রসেস। | ০ থেকে ২০০ (পরিবর্তনশীল) |
| BTOP (বাউন্ড টপ) | প্রসেসটি একটি TOP অ্যাপ্লিকেশন দ্বারা আবদ্ধ। | 100 |
| BFGS | বাউন্ড ফোরগ্রাউন্ড সার্ভিস (সাধারণত সিস্টেম-বাউন্ড)। | 0 |
| PREV (পূর্ববর্তী) | বর্তমান প্রসেসের আগে ব্যবহারকারী যে শেষ প্রসেসে ছিলেন। | ৭০০ |
| CACHED | ব্যাকগ্রাউন্ড অ্যাপ যা নিরাপদে বন্ধ করা যেতে পারে। | ৯০০ থেকে ৯৯৯ |
পরিষেবা বাইন্ডিংয়ের প্রভাব
যখন কোনও ক্লায়েন্ট প্রসেস (যেমন, TOP অবস্থায় থাকা কোনও অ্যাপ) সার্ভার প্রসেসে কোনও পরিষেবার সাথে কানেক্ট করে, তখন সার্ভার প্রসেস প্রায়শই একটি উন্নত অগ্রাধিকার উত্তরাধিকার সূত্রে পায়। এটি
নিশ্চিত করে যে ক্লায়েন্টের যতক্ষণ প্রয়োজন ততক্ষণ পরিষেবাটি উপলভ্য থাকবে।

BIND ফ্ল্যাগ ব্যবহার করে ইনহেরিটেন্স নিয়ন্ত্রণ করা
Context.BIND_AUTO_CREATE ব্যবহার করার সময় ইনহেরিটেন্স হল ডিফল্ট অ্যাকশন।
তবে, ডেভেলপাররা bindService()-এ বিভিন্ন ফ্ল্যাগ ব্যবহার করে টার্গেট প্রসেসের গুরুত্বের উপর বাইন্ডিং কীভাবে প্রভাব ফেলে তা নিয়ন্ত্রণ করতে পারেন।
OOM স্কোরের জন্য গুরুত্বপূর্ণ BIND ফ্ল্যাগ
সিস্টেম-ওয়াইড মেমরি প্রেসার ম্যানেজ করার সময় নিম্নলিখিত ফ্ল্যাগগুলি সবচেয়ে প্রাসঙ্গিক:
BIND_AUTO_CREATE: সবচেয়ে সাধারণ ফ্ল্যাগ। এটি নিশ্চিত করে যে পরিষেবা প্রসেস শুরু করা হয়েছে এবং বাইন্ডিং যতক্ষণ থাকবে ততক্ষণ চালু থাকবে। ডিফল্ট হিসেবে, এটি ক্লায়েন্টের সাথে ম্যাচ করার জন্য সার্ভার প্রসেসের অগ্রাধিকারও বাড়ায়।BIND_NOT_FOREGROUND: টার্গেট পরিষেবার প্রসেসকে ফোরগ্রাউন্ড শিডিউলিং অগ্রাধিকার (সিপিইউ অগ্রাধিকার) হিসেবে উন্নীত করা থেকে আটকায়। তবে, এটি এখনও মেমরি প্রায়োরিটি (oom_score_adj) বাড়ানোর অনুমতি দেয়। এটি ব্যাকগ্রাউন্ডে চলা কাজের জন্য উপযোগী যা CPU সাইকেলের জন্য UI-এর সাথে প্রতিযোগিতা করে না কিন্তু এখনও বন্ধ হওয়া থেকে সুরক্ষিত থাকে।BIND_WAIVE_PRIORITY: একটি খুব শক্তিশালী ফ্ল্যাগ যা সিস্টেমকে নির্দেশ দেয় যাতে টার্গেট প্রসেসের শিডিউলিং বা মেমরি ম্যানেজমেন্টের অগ্রাধিকার প্রভাবিত না হয়। পরিষেবা প্রসেসটি এমনভাবে ম্যানেজ করা হবে যেন এটি LRU তালিকার একটি সাধারণ ব্যাকগ্রাউন্ড প্রসেস, যা বাউন্ড থাকা অবস্থাতেও OOM কিলিংয়ের জন্য উপযুক্ত করে তোলে।BIND_ABOVE_CLIENT: এর অর্থ হল, ক্লায়েন্ট অ্যাপের চেয়ে পরিষেবাটি বেশি গুরুত্বপূর্ণ। সিস্টেমের মেমরি খালি করার প্রয়োজন হলে, এটি বাউন্ড পরিষেবা বন্ধ করার আগে ক্লায়েন্ট অ্যাপ বন্ধ করতে পছন্দ করবে। এটিBIND_AUTO_CREATE-এর চেয়ে "আরও শক্তিশালী" কারণ এটি ক্লায়েন্টের খরচে পরিষেবার জন্য অতিরিক্ত সুরক্ষার স্তর প্রদান করে।BIND_NOT_PERCEPTIBLE: টার্গেট করা পরিষেবার গুরুত্ব কমিয়েPERCEPTIBLEলেভেলের নিচে নিয়ে আসে, যার ফলে সিস্টেম আরও গুরুত্বপূর্ণ ব্যবহারকারী-উপলব্ধ প্রসেসের জন্য জায়গা করতে মেমরি রিক্লেম করতে পারে।
হ্যান্ডস-অন: বাইন্ডিং এফেক্ট পর্যবেক্ষণ করা
TOP অ্যাপ থেকে বাইন্ডিং কীভাবে আলাদা প্রসেসের অবস্থাকে প্রভাবিত করে তা দেখানোর জন্য আমরা MemoryLab অ্যাপ্লিকেশন ব্যবহার করব।
১. MemoryLab লঞ্চ করুন
নিম্নলিখিত কমান্ড অ্যাপটি চালু করে। এটি খোলার পরে, অ্যাপটি যাতে ফোরগ্রাউন্ডে থাকে তা নিশ্চিত করুন (এখনই হোম প্রেস করবেন না বা অ্যাপ পরিবর্তন করবেন না)।
adb shell am start -n com.android.memorylab/.MainActivity
২. প্রক্রিয়া শনাক্ত করুন
বাইন্ড করার আগে প্রসেসের স্ট্যাটাস চেক করুন। MemoryLab একটি প্রসেসে এর প্রধান UI রান করে এবং
এতে একটি RemoteService আছে যা :remote প্রসেসে রান করে।
adb shell dumpsys activity processes com.android.memorylab
স্যাম্পেল আউটপুট স্নিপেট:
Process OOM control (154 total, non-act at 7, non-svc at 7):
Proc #0: fg T/A/TOP LCMNFUATI t: 0 13470:com.android.memorylab/u0a417 (top-activity)
oom: max=1001 curRaw=0 setRaw=0 cur=0 set=0
state: cur=TOP set=TOP lastRss=0.00 lastCachedRss=0.00
আপনি TOP স্ট্যাটাসে মূল প্রসেস com.android.memorylab দেখতে পাবেন। :remote
প্রসেস এখনও শুরু হয়নি।
৩. ট্রিগার বাইন্ডিং
পরিষেবা বাইন্ডিং ট্রিগার করতে অ্যাপে ব্রডকাস্ট পাঠান:
adb shell am broadcast -a com.android.memorylab.LEAK_BINDER
৪. উন্নত স্ট্যাটাস দেখুন
প্রসেসের স্ট্যাটাস আবার চেক করুন:
adb shell dumpsys activity processes | grep -A 10 "com.android.memorylab"
স্যাম্পেল আউটপুট স্নিপেট:
Proc # 1: vis F/ /BTOP ---NFUATI t: 0 13560:com.android.memorylab:remote/u0a417 (service)
com.android.memorylab/.RemoteService<=Proc{13470:com.android.memorylab/u0a417}
oom: max=1001 curRaw=100 setRaw=100 cur=100 set=100
state: cur=BTOP set=BTOP lastRss=0.00 lastCachedRss=0.00
:remote প্রসেস এখন চলছে এবং BTOP (Bound TOP) স্ট্যাটাসে আছে,
যার oom_score_adj হল ১০০। এটি সাধারণ ব্যাকগ্রাউন্ড পরিষেবার (যা 500 বা তার বেশি হবে)
তুলনায় অনেক বেশি সুরক্ষিত। <=Proc{...}
চিহ্নটি দেখায় যে কোন প্রসেস এই অগ্রাধিকার বৃদ্ধির জন্য দায়ী।
৫. ব্যাকগ্রাউন্ডে পাঠান
ডিভাইসের হোম বোতাম প্রেস করুন। রাজ্যগুলি আবার চেক করুন:
adb shell dumpsys activity processes | grep -A 10 "com.android.memorylab"
স্যাম্পেল আউটপুট স্নিপেট:
Proc # 2: prev b/ /LAST --------I t: 0 13560:com.android.memorylab:remote/u0a417 (service)
com.android.memorylab/.RemoteService<=Proc{13470:com.android.memorylab/u0a417}
oom: max=1001 curRaw=700 setRaw=700 cur=700 set=700
state: cur=LAST set=LAST lastRss=0.00 lastCachedRss=0.00
Proc # 1: prev b/ /LAST --------I t: 0 13470:com.android.memorylab/u0a417 (previous)
oom: max=1001 curRaw=700 setRaw=700 cur=700 set=700
state: cur=LAST set=LAST lastRss=209MB lastCachedRss=0.00
এখন দুটি প্রসেসই কম অগ্রাধিকারের অবস্থায় (PREV /
oom_score_adj 700) স্থানান্তরিত হয়েছে, কারণ ক্লায়েন্ট প্রসেস আর TOP নেই। (মনে রাখবেন:
স্টেট ডাম্পে LAST বলতে LAST_ACTIVITY ইন্টার্নাল স্টেটকে বোঝায়, যা
হাই-লেভেল সামারিতে PREV-এর সাথে ম্যাপ করে)।
procstats-এর মাধ্যমে বিশ্লেষণ করা হচ্ছে
procstats টুলটি এই রাজ্যগুলির একটি ঐতিহাসিক ভিউ প্রদান করে।
# View stats for MemoryLab over the last hour
adb shell dumpsys procstats --hours 1 com.android.memorylab
স্যাম্পেল আউটপুট স্নিপেট:
* com.android.memorylab / u0a417 / v37:
* Prc com.android.memorylab / u0a417 / v37:
TOTAL: 0.89% (0.00-0.00-0.00/0.00-0.00-0.00/210MB-210MB-210MB over 1)
Top: 0.89% (0.00-0.00-0.00/0.00-0.00-0.00/210MB-210MB-210MB over 1)
* Prc com.android.memorylab:remote / u0a417 / v37:
TOTAL: 0.19%
Bnd Top: 0.19%
এখানে, Bnd Top রিমোট প্রসেস TOP স্ট্যাটাসে কোনও অ্যাপ্লিকেশনের সাথে আবদ্ধ হয়ে
কত শতাংশ সময় ব্যয় করেছে তা নির্দেশ করে।
Perfetto-এর মাধ্যমে বাইন্ডিং ক্যাপচার ও বিশ্লেষণ করা
dumpsys আপনাকে একটি স্ন্যাপশট দিলেও, Perfetto আপনাকে ঠিক সেই মুহূর্তটি দেখতে দেয়
যখন একটি বাইন্ডিং ঘটে এবং রিয়েল-টাইমে OOM স্কোর কীভাবে পরিবর্তিত হয়।
১. ট্রেস রেকর্ড করুন
এমন কনফিগারেশন ব্যবহার করুন যাতে linux.process_stats এবং am atrace বিভাগ অন্তর্ভুক্ত থাকে:
adb shell perfetto -c - --txt -o /data/misc/perfetto-traces/service_bindings.perfetto-trace <<EOF
buffers: { size_kb: 65536 }
data_sources: {
config {
name: "linux.process_stats"
process_stats_config { proc_stats_poll_ms: 100 }
}
}
data_sources: {
config {
name: "linux.ftrace"
ftrace_config { ftrace_events: "am/am_proc_bound" }
}
}
duration_ms: 15000
EOF
২. কোয়েরি OOM স্কোর ট্রানজিশন
PerfettoSQL ব্যবহার করে, আপনি দেখতে পারবেন যে UI প্রসেসের তুলনায় রিমোট প্রসেসের OOM স্কোর কীভাবে পরিবর্তিত হয়েছে:
SELECT ts, p.name, value AS oom_score_adj
FROM counter c
JOIN process_counter_track t ON c.track_id = t.id
JOIN process p USING (upid)
WHERE p.name LIKE 'com.android.memorylab%'
AND t.name = 'oom_score_adj'
ORDER BY ts;
৩. বাইন্ডিং ইভেন্ট শনাক্ত করো
ঠিক কখন একটি বাইন্ডিং ডিপেন্ডেন্সি প্রতিষ্ঠিত হয়েছিল এবং কোন প্রক্রিয়াটি এটি শুরু করেছিল তা দেখতে, এই কোয়েরিটি ব্যবহার করুন:
SELECT
s.ts,
p.name AS process_name,
t.name AS thread_name,
s.name AS slice_name
FROM slice s
JOIN thread_track tt ON s.track_id = tt.id
JOIN thread t USING (utid)
JOIN process p USING (upid)
WHERE s.name LIKE 'bindService:{com.android.memorylab%';
সিস্টেম-টু-অ্যাপ বাইন্ডিং
মূল কার্যকারিতা প্রদান করতে, Android সিস্টেম নিজেই প্রায়ই থার্ড-পার্টি অ্যাপের পরিষেবার সাথে বাইন্ড করে। প্রায়শই এইসব বাইন্ডিংয়ের লক্ষ্য হল লেটেন্সি কমানো। কোনও প্রসেস চালু ও মেমরিতে রাখার মাধ্যমে, সিস্টেম "কোল্ড স্টার্ট" (APK লোড করা, রানটাইম শুরু করা এবং অ্যাপ্লিকেশন অবজেক্ট তৈরি করা) প্রসেসের অতিরিক্ত খরচ এড়িয়ে যায়, যখন কোনও গুরুত্বপূর্ণ ব্যবহারকারীর ইন্টার্যাকশন ঘটে। ব্যাকগ্রাউন্ড ইভেন্টের স্ট্রিম ম্যানেজ করতে হয় এমন অ্যাপের ক্ষেত্রে ঘন ঘন কোল্ড স্টার্ট এড়াতে অন্যান্য বাইন্ডিং রয়েছে।
এখানে কিছু বাস্তব উদাহরণ দেওয়া হল যা আপনি সাধারণ ডিভাইসে দেখতে পাবেন:
VoiceInteractor
ব্যবহারকারীরা আশা করেন যে তাদের ফোনের OS-এ একটি ডিজিটাল অ্যাসিস্ট্যান্ট এম্বেড করা থাকবে, যাতে তারা একটি স্পোকেন হটওয়ার্ড বা একটি দ্রুত ইনপুট জেসচারের মাধ্যমে তাৎক্ষণিকভাবে এটিকে কল করতে পারেন এবং যাতে ইন্টার্যাকশন মসৃণ এবং নির্বিঘ্ন হয়।
অ্যাসিস্ট্যান্ট ট্রিগার হলে (যেমন Google Pixel ফোনে "OK Google" হটওয়ার্ড), ডিজিটাল অ্যাসিস্ট্যান্টকে সাথে সাথে উত্তর দিতে হয়। এটি নিশ্চিত করতে,
system_server ব্যবহারকারীর বেছে নেওয়া ভয়েস ইন্টার্যাকশন
পরিষেবা-এর সাথে স্থায়ীভাবে যুক্ত থাকে।

আপনি যদি প্রসেসের স্ট্যাটাস চেক করেন (যেমন, dumpsys activity processes ব্যবহার করে), তাহলে
আপনি হয়ত BFGS (বাউন্ড ফোরগ্রাউন্ড সার্ভিস) স্ট্যাটাসে
com.google.android.googlequicksearchbox:interactor-এর মতো প্রসেস দেখতে পাবেন, যা system_server (UID 1000) থেকে
বাইন্ডিংয়ের মাধ্যমে চালু রাখা হয়েছে।
NotificationListenerService
কিছু সিস্টেম-টু-অ্যাপ বাইন্ডিংয়ের ক্ষেত্রে, লক্ষ্য লেটেন্সি নয়, বরং ঘন ঘন কোল্ড স্টার্ট
প্রতিরোধ করা।
NotificationListenerService,
নতুন বিজ্ঞপ্তি পোস্ট বা সরানো হলে সিস্টেম থেকে কল রিসিভ করে এমন পরিষেবা
এর একটি প্রধান উদাহরণ। একজন সাধারণ স্মার্টফোন ব্যবহারকারী সারাদিনে
শত শত বিজ্ঞপ্তি পেতে পারেন। সিস্টেম যদি কোনও বিজ্ঞপ্তি লিসেনার থেকে আনবাউন্ড হয়ে যায়, তাহলে সেই অ্যাপের প্রসেস ক্যাশে করা স্ট্যাটাসে চলে যেতে পারে এবং LMK-এর মাধ্যমে বন্ধ হয়ে যেতে পারে।
পরবর্তী বিজ্ঞপ্তি আসার সময় - সম্ভবত কয়েক সেকেন্ড পরে - সিস্টেমকে ইভেন্টটি ডেলিভার করার জন্য অ্যাপের প্রসেস আবার কোল্ড স্টার্ট করতে বাধ্য করা হবে। প্রসেস বন্ধ করা ও কোল্ড স্টার্ট করার এই চক্র চলতে থাকলে, ব্যাকগ্রাউন্ডে প্রসেস বাউন্ড ও চালু রাখার তুলনায় অনেক বেশি সিপিইউ ও ব্যাটারি খরচ হয়।
লঞ্চারের "-১ স্ক্রিন" (নিউজ ফিড)
আধুনিক লঞ্চার অ্যাপ সাধারণত মূল নেভিগেশনাল কার্যকারিতা (হোম আইকন এবং উইজেট) একটি নিউজ ফিডের সাথে একত্রিত করে যা লঞ্চার স্ক্রিনের একটিতে উপলভ্য এবং লঞ্চার UX-এর সাথে নির্বিঘ্নে ইন্টিগ্রেট করা হয়। নিউজ ফিড অন্য কোনও অ্যাপের মাধ্যমে প্রদান করা হতে পারে। যেমন, Google Pixel-এ লঞ্চার, Google অ্যাপের মাধ্যমে প্রদান করা ফিডের সাথে ইন্টিগ্রেট করে।
নিউজ ফিড দেখার জন্য আপনার হোম স্ক্রিনে বাঁদিকে সোয়াইপ করার সময়, ট্রানজিশন মসৃণ হতে হবে। লঞ্চার এটি করে অ্যাপে একটি পরিষেবা ইন্টারফেসের সাথে বাইন্ড করে যা নিউজ ফিড প্রদান করে এবং যতক্ষণ লঞ্চার চালু থাকে ততক্ষণ সেই বাইন্ডিং চালু রাখে। এর ফলে, আপনি না দেখলেও ফিডের কন্টেন্ট রেন্ডার করা এবং মেমরিতে রেডি থাকে।
অন্যান্য সাধারণ উদাহরণ
- লঞ্চার (HOME_APP_ADJ): লঞ্চার অ্যাপের (Home) অগ্রাধিকার তালিকায়
নিজস্ব বিশেষ স্লট আছে। সবসময় কোনও পরিষেবার সাথে যুক্ত না থাকলেও, এটি
HOME_APP_ADJ(সাধারণত ৬০০) অ্যাসাইন করা হয়। সিস্টেম লঞ্চারকে চালু রাখতে পছন্দ করে, কারণ ব্যবহারকারী ঘন ঘন এটিতে ফিরে আসেন। আসলে, সিস্টেম লঞ্চার বন্ধ করার চেয়ে আগে ব্যবহার করা অ্যাপ (PREV_APP_ADJ = 700) বন্ধ করতে বেশি পছন্দ করবে, কারণ লঞ্চার বন্ধ করলে কোনও অ্যাপ থেকে বেরিয়ে আসার সময় ব্যবহারকারীর অভিজ্ঞতা খারাপ হবে, কারণ লঞ্চার কোল্ড স্টার্ট হওয়ার জন্য ব্যবহারকারীকে অপেক্ষা করতে হবে। - ইনপুট পদ্ধতি এডিটর (IME): আপনি টাইপ করার সময়, সিস্টেম আপনার বেছে নেওয়া কীবোর্ড অ্যাপের (যেমন, Gboard) সাথে বাইন্ড করে। কীবোর্ড সাময়িকভাবে লুকানো থাকলেও, এটি কীবোর্ড প্রসেসকে উন্নত অবস্থায় রাখে। এটি নিশ্চিত করে যে আপনি অন্য কোনও টেক্সট ফিল্ডে ট্যাপ করলে কীবোর্ডটি সাথে সাথে আবার দেখা যাবে।
- NFC পেমেন্ট: পেমেন্ট করার জন্য আপনার ফোন ট্যাপ করলে, সিস্টেম NFC পেমেন্ট পরিষেবার (যেমন, Google Wallet) সাথে বাইন্ড করে। এইসব ট্রানজ্যাকশনের ক্ষেত্রে প্রায়ই মার্চেন্ট টার্মিনাল থেকে কঠোর রিয়েল-টাইম প্রয়োজনীয়তা থাকে। পেমেন্ট অ্যাপ কোল্ড স্টার্ট করতে হলে, ট্রানজ্যাকশন টাইম-আউট হয়ে যেতে পারে এবং ব্যর্থ হতে পারে।
ট্রেডঅফ ও পারফর্ম্যান্স ক্লিফ
পারফর্ম্যান্স ও নির্ভুলতার জন্য বাইন্ডিং প্রয়োজন হলেও, এর ফলে সিস্টেমের মেমরি হেল্থের উপর প্রভাব পড়ে।
- কম ফ্লেক্সিবিলিটি: প্রতিটি বাউন্ড প্রসেস হল এমন একটি প্রসেস যা LMK সহজে বন্ধ করতে পারে না। এর ফলে ক্যাশে করা প্রসেসের "কুশন" কমে যায় যা সিস্টেম চাপের মধ্যে মেমরি খালি করতে ব্যবহার করতে পারে।
- পারফর্ম্যান্স ক্লিফ আরও খারাপ করা: অনেক বেশি প্রসেস বাউন্ড করা থাকলে, সিস্টেমের কাছে বন্ধ করার মতো ব্যাকগ্রাউন্ড প্রসেস প্রায় থাকেই না। মেমরির উপর চাপ বাড়লে, সিস্টেম অনেক দ্রুত "পারফর্ম্যান্স ক্লিফ থেকে পড়ে যাবে", কারণ এটি আরও গুরুত্বপূর্ণ প্রসেস বন্ধ করতে বা পৃষ্ঠা ক্যাশে থ্র্যাশ করতে বাধ্য হয়।
সাধারণ পরিষেবা বাইন্ডিং অ্যান্টি-প্যাটার্ন
যেহেতু সার্ভিস বাইন্ডিং সরাসরি oom_score_adj-কে উন্নত করে, তাই আপনি কীভাবে বাইন্ডিং অর্জন বা গঠন করেন তার সূক্ষ্ম লাইফসাইকেল
ভুলগুলি বিশেষাধিকারপ্রাপ্ত অবস্থায় (BTOP, BFGS, বা PERC) ঘণ্টার পর ঘণ্টা প্রচুর পরিমাণে
মেমরি পিন করতে পারে। বাউন্ড পরিষেবা ডিজাইন বা অডিট করার সময়
এইসব সাধারণ অ্যান্টি-প্যাটার্নের ব্যাপারে সতর্ক থাকুন।
দীর্ঘদিন ধরে থাকা ক্লায়েন্টের ক্ষেত্রে unbindService() ভুলে যাওয়া
Application সিঙ্গলটন, ব্যাকগ্রাউন্ড ম্যানেজার বা
Activity থেকে কোনও পরিষেবায় বাইন্ড করা, যা onStop()-এ ম্যাচিং unbindService() ছাড়া
onStart()-এ bindService() কল করে, ServiceConnection লিক করে।
যতক্ষণ পর্যন্ত সেই বাইন্ডিং অ্যাক্টিভ থাকে, টার্গেট প্রসেস ক্লায়েন্টের উন্নত অগ্রাধিকার
উত্তরাধিকার সূত্রে পায়। ক্লায়েন্ট যদি কোনও পারসিস্টেন্ট সিস্টেম কম্পোনেন্ট বা ফোরগ্রাউন্ড অ্যাপ হয়, তাহলে বাউন্ড সার্ভিস প্রসেস BFGS বা BTOP-এ অনির্দিষ্টকালের জন্য পিন করা থাকে
(procstats-এ ১০০%-এর কাছাকাছি দেখায়), যা সার্ভিস সম্পূর্ণভাবে আইডল থাকলেও
LMK-কে এর মেমরি রিক্লেম করতে বাধা দেয়।
প্রতিকার: যে কম্পোনেন্টের জন্য স্কোপ বাইন্ডিং প্রয়োজন, সেটির লাইফসাইকেলের সাথে কঠোরভাবে স্কোপ বাইন্ডিং করুন অথবা একটি আইডল টাইমআউট প্রয়োগ করুন যা কিছু সময় কোনও অ্যাক্টিভিটি না হওয়ার পরে unbindService() কল করে। প্রতিটি পৃথক RPC কলে আনবাইন্ডিং এবং রিবাইন্ডিং এড়িয়ে চলুন, যা প্রসেস থ্র্যাশিং এবং বারবার বাইন্ডার সেটআপ ওভারহেডের কারণ হয়;
পরিবর্তে, একটি ছোট নিষ্ক্রিয় টাইমারের (যেমন, ৫ থেকে ৩০ সেকেন্ড) পিছনে কাজের বার্স্ট একত্রিত করুন।
মেমরি-ইনটেনসিভ UI-এর সাথে বাউন্ড সার্ভিস কো-লোকেট করা
ডিফল্ট হিসেবে, APK-এর সব কম্পোনেন্ট একই প্রসেসে রান করে। আপনার অ্যাপ যদি
আপনার প্রধান Activity-এর মতো একই প্রসেসে একটি লাইটওয়েট বাউন্ড পরিষেবা (যেমন একটি NotificationListenerService, একটি
উইজেট প্রদানকারী, বা একটি প্লাগইন পরিষেবা যা সিস্টেম বা লঞ্চার বাইন্ড করে)
প্রকাশ করে, তাহলে পুরো প্রসেসটি পরিষেবার উন্নত অবস্থা (BFGS বা PERC, সাধারণত ২০০ বা
তার কম oom_score_adj) উত্তরাধিকার সূত্রে পায়।
ব্যবহারকারী আপনার অ্যাপের UI খুললে, প্রসেসটি বড় ভিউ হায়ারার্কি, ডিকোড করা বিটম্যাপ ও গ্রাফিক্স বাফার
অ্যালোকেট করে। ব্যবহারকারী অন্য কোথাও নেভিগেট করলে, প্রসেসটি CACHED (oom_score_adj-এর ৯০০ বা তার বেশি) পর্যন্ত কমে যায় না
কারণ অ্যাক্টিভ সার্ভিস বাইন্ডিং প্রসেসটিকে উন্নত রাখে। এর ফলে দুটি
সমস্যা দেখা দেয়:
- ব্যাকগ্রাউন্ড মেমরি কম্প্যাকশন নেই: সিস্টেমের
CachedAppOptimizerশুধুমাত্র প্রসেসগুলিCACHEDঅবস্থায় প্রবেশ করার পরে কম্প্যাক্ট করে। - কোনও ক্যাশে করা-LRU মেমরি ট্রিম বা LMK রিক্লেমেশন নেই: সিস্টেম
ক্যাশে করা LRU তালিকার সাথে যুক্ত ব্যাকগ্রাউন্ড ট্রিম কলব্যাক ডেলিভার করে না
(
TRIM_MEMORY_BACKGROUNDএবং তার পরবর্তী ভার্সন) যখন কোনও পরিষেবা বাইন্ডিং প্রসেসকে একটি উন্নত অবস্থায় রাখে। আপনার অ্যাপTRIM_MEMORY_UI_HIDDENবাActivity.onStop()-এ UI রিসোর্স স্পষ্টভাবে রিলিজ না করলে, পিক UI অ্যালোকেশন RAM-এ একটি বিশেষ OOM স্কোরে পিন করা থাকে যেখানে LMK সহজে সেগুলি রিক্লেম করতে পারে না।
প্রতিকার: UI ক্যাশে, ডিকোড করা বিটম্যাপ এবং ভিউ রেফারেন্স স্পষ্টভাবে
উচ্ছেদ করুন যখন আপনার UI দৃশ্যমান হওয়া বন্ধ হয়ে যায়, Activity.onStop(),
ComponentCallbacks2.onTrimMemory(TRIM_MEMORY_UI_HIDDEN),
Application.ActivityLifecycleCallbacks, অথবা
ProcessLifecycleOwner ব্যবহার করে। বিকল্প হিসেবে,
android:process ম্যানিফেস্ট অ্যাট্রিবিউট ব্যবহার করে সবসময়-বাউন্ড পরিষেবাটি আলাদা, হালকা প্রসেসে সরিয়ে দিন যাতে সিস্টেম আপনার মূল UI
প্রসেসটি CACHED স্ট্যাটাসে সরিয়ে দিতে পারে এবং স্বাধীনভাবে এর মেমরি কম্প্যাক্ট বা রিক্লেম করতে পারে।
অগ্রাধিকার-পরিত্যাগ করা ফ্ল্যাগ বাদ দেওয়া
BIND_AUTO_CREATE-এর সাথে bindService()-কে কল করলে, কলারের সম্পূর্ণ শিডিউলিং ও মেমরি প্রায়োরিটি
টার্গেট পরিষেবায় ট্রান্সফার হয়ে যায়। যখন কোনও ফোরগ্রাউন্ড
অ্যাপ শুধুমাত্র BIND_AUTO_CREATE ব্যবহার করে ব্যাকগ্রাউন্ড অ্যানালিটিক্স, লগিং বা প্রিফেচিং পরিষেবার সাথে বাইন্ড করে,
তখন এটি অনিচ্ছাকৃতভাবে সেই ব্যাকগ্রাউন্ড ওয়ার্কারকে
BTOP-এ প্রোমোট করে।
প্রতিকার: ফোরগ্রাউন্ড UI-এর মতো একই সুরক্ষা লেভেলের প্রয়োজন নেই এমন সহায়ক বা বেস্ট-এফর্ট পরিষেবার সাথে বাইন্ড করার সময়,
BIND_AUTO_CREATE-এর সাথে BIND_WAIVE_PRIORITY, BIND_NOT_FOREGROUND বা BIND_NOT_PERCEPTIBLE
একত্রিত করুন যাতে সিস্টেম এখনও ক্যাশে করা LRU তালিকায় টার্গেট প্রসেস ম্যানেজ করতে পারে।
← লোকালিটি | ↑ উপরে | সিস্টেম-জুড়ে →