যখন স্মৃতিশক্তির ব্যবহার খতিয়ে দেখার প্রয়োজন হয়, তখন কোন ধরনের স্মৃতি সবচেয়ে গুরুত্বপূর্ণ তা শনাক্ত করতে উচ্চ-স্তরের মূল্যায়ন সরঞ্জাম দিয়ে শুরু করুন।
ডাম্পসিস মেমইনফো
কোনো অ্যাপ্লিকেশনের মেমরি ব্যবহারের একটি সার্বিক ধারণা পাওয়ার সবচেয়ে প্রচলিত উপায় হলো dumpsys meminfo । সমস্ত মেমরি ম্যাপিং সহ একটি বিস্তারিত বিবরণ দেখতে, প্রায়শই -a ফ্ল্যাগটি অন্তর্ভুক্ত করা সহায়ক হয়:
adb shell dumpsys meminfo -a <package_name_or_pid>
এখানে কিছুটা মেমোরি চাপের মধ্যে থাকা একটি অ্যাপ্লিকেশনের নমুনা আউটপুট দেওয়া হলো (উচ্চ SwapPss লক্ষ্য করুন):
** MEMINFO in pid 4562 [com.android.memorylab] **
Pss Private Private SwapPss Rss Heap Heap Heap
Total Dirty Clean Dirty Total Size Alloc Free
------ ------ ------ ------ ------ ------ ------ ------
Native Heap 394 268 64 17440 4264 29416 18128 8040
Dalvik Heap 165 8 0 672 8196 40949 32757 8192
Dalvik Other 47 28 0 604 1132
Stack 112 108 4 312 120
...
TOTAL 33197 580 788 21920 167776 70365 50885 16232
App Summary
Pss(KB) Rss(KB)
------ ------
Java Heap: 12 32608
Native Heap: 268 4264
Code: 724 125672
Stack: 108 120
Graphics: 0 0
Private Other: 256
System: 31829
Unknown: 5112
TOTAL PSS: 33197 TOTAL RSS: 167776 TOTAL SWAP PSS: 21920
Objects
Views: 15 ViewRootImpl: 1
AppContexts: 5 Activities: 1
...
ডেটা ব্যাখ্যা করা
- পিএসএস টোটাল : আনুপাতিক সেট সাইজ। এটি হলো
Private Dirtyযোগফল।-
Private Clean+ অন্যান্য প্রসেসের (যেমন জাইগোট বুট ইমেজ) সাথে আপনার প্রসেসের ন্যায্য মেমোরির ভাগ। "এই অ্যাপটি কী পরিমাণ মেমোরির জন্য দায়ী" তা বোঝার জন্য এটিই সেরা পরিমাপক।
-
- প্রাইভেট ডার্টি : এটি এমন র্যাম যা শুধুমাত্র আপনার প্রসেস ব্যবহার করছে এবং যা পরিবর্তিত হয়েছে (অথবা এটি অ্যানোনিমাস মেমরি)। মেমরি লিক খুঁজে বের করার জন্য এটি সবচেয়ে গুরুত্বপূর্ণ সংখ্যা, কারণ এই মেমরি ড্রপ করা যায় না।
- প্রাইভেট ক্লিন : র্যামের এমন একটি অংশ যা শুধুমাত্র আপনার প্রসেস ব্যবহার করে, কিন্তু এটি স্টোরেজে থাকা কোনো ফাইলের (যেমন একটি DEX ফাইল) একটি অপরিবর্তিত অনুলিপি। মেমোরি কম থাকলে অপারেটিং সিস্টেম এটিকে বাদ দিয়ে দিতে পারে।
- SwapPss : যে মেমরি সংকুচিত করে ZRAM-এ সোয়াপ করা হয়েছে। এটি ঘটতে পারে হয় সিস্টেমের উপর মেমরির চাপ থাকার কারণে, অথবা অ্যান্ড্রয়েড রানটাইম ব্যাকগ্রাউন্ড প্রসেসগুলোকে কম্প্যাক্ট করার জন্য (তাদের অব্যবহৃত বা নিষ্ক্রিয় পেজগুলোকে ZRAM-এ সরিয়ে) শনাক্ত করার কারণে।
dumpsysউদাহরণটিতে,Native HeapএবংDalvik Heapপ্রায় পুরোটাই ZRAM-এ সরানো হয়েছে।
- অ্যাপের সারাংশ : একটি উচ্চতর শ্রেণিবিন্যাস যা বিস্তারিত সারিগুলোকে একত্রিত করে বোধগম্য ভাগে ভাগ করে।
- অবজেক্টস : লিক হওয়া
ActivitiesএবংViewRootImplইনস্ট্যান্স ট্র্যাক করার জন্য এটি উপযোগী। আপনি যদি আপনার অ্যাপ থেকে বেরিয়ে আসেন এবং জোরপূর্বক গার্বেজ কালেকশন (GC) করেন, তাহলেActivitiesসংখ্যা ০-তে ফিরে আসা উচিত।
হাতে-কলমে অনুশীলন: মেমইনফো ব্যবহার করে দ্রুত ট্রায়েজ
এই অনুশীলনীতে দেখানো হয়েছে কিভাবে বিভিন্ন ধরণের অ্যালোকেশন meminfo তে প্রদর্শিত হয়।
অ্যাপটি চালু করুন :
adb shell am start -W -n com.android.memorylab/.MainActivityবেসলাইন মেমরি পরীক্ষা করুন :
adb shell dumpsys meminfo -s com.android.memorylab(
-sফ্ল্যাগটি মেমরি ক্যাটাগরিগুলোর একটি সংক্ষিপ্ত ও সারগর্ভ সারসংক্ষেপ প্রদান করে)।জাভা মেমরি বরাদ্দ করুন : অ্যাপের মধ্যে থাকা ‘জাভা মেমরি বরাদ্দ করুন (10MB)’ বোতামটি ৩ বার ট্যাপ করুন।
পরিবর্তনটি লক্ষ্য করুন : আবার
meminfo -sচালান। আপনি দেখবেন যে জাভা হিপ ভ্যালু প্রায় ৩০,০০০ কিলোবাইট (৩০ মেগাবাইট) বৃদ্ধি পেয়েছে।নেটিভ মেমরি বরাদ্দ করুন : 'নেটিভ মেমরি বরাদ্দ করুন (১জিবি অসংকোচনীয়)' বোতামটি একবার ট্যাপ করুন।
পরিবর্তনটি লক্ষ্য করুন : আবার
meminfo -sচালান। এখন Native Heap-এর মানে একটি ব্যাপক বৃদ্ধি (~১,০০০,০০০ KB) দেখা যাবে।
বৈশ্বিক দৃষ্টিভঙ্গি
পুরো সিস্টেম জুড়ে মেমরি ব্যবহার দেখতে, চালান:
adb shell dumpsys meminfo
এটি র্যাম ব্যবহারের একটি সারসংক্ষেপ প্রদান করে, যার মধ্যে মোট র্যাম, খালি র্যাম এবং PSS অনুযায়ী সাজানো প্রসেসের একটি তালিকা অন্তর্ভুক্ত রয়েছে।
মূল সিস্টেম মেট্রিক্স
- ZRAM : র্যামের সংকুচিত সোয়াপ।
- DMA-BUF : গ্রাফিক্স এবং শেয়ার্ড মেমরি বাফার। আধুনিক অ্যান্ড্রয়েড সংস্করণগুলো UI রেন্ডারিংয়ের জন্য ব্যাপকভাবে DMA-BUF ব্যবহার করে। যদি
DMA-BUFমোট পরিমাণ খুব বেশি হয়, তাহলে/sys/kernel/debug/dma_buf/bufinfoব্যবহার করে গ্রাফিক্স-নির্ভর প্রসেসগুলো তদন্ত করুন। - হারানো র্যাম (Lost RAM) : এমন মেমরি যা কার্নেল বা কোনো প্রসেস দ্বারা ব্যবহৃত হয় না (যেমন, হার্ডওয়্যার-সংরক্ষিত অঞ্চল)।
মানচিত্র দেখান
কোনো প্রসেসের মেমরি ম্যাপিংয়ের আরও বিশদ বিশ্লেষণের জন্য showmap ব্যবহার করুন। এই টুলটি /proc/<pid>/smaps থেকে ডেটা পড়ে।
adb shell showmap <pid>
showmap প্রসেসের প্রতিটি মেমরি ম্যাপ তালিকাভুক্ত করে। যে মূল ম্যাপিংগুলো খুঁজতে হবে সেগুলো হলো:
-
[anon:scudo:primary]অথবা[anon:libc_malloc]: নেটিভ হিপ। আধুনিক অ্যান্ড্রয়েড সংস্করণগুলো স্কুডো অ্যালোকেটর ব্যবহার করে। -
*.art: জাভা হিপ ইমেজ (যেমন, বুট ইমেজ)। -
[anon:dalvik-main space]: জাভার প্রধান হিপ। -
*.so: শেয়ার্ড লাইব্রেরি। -
*.{oat,dex,odex,vdex}: কম্পাইল করা DEX কোড।
সবচেয়ে বেশি ব্যক্তিগত মেমরি ব্যবহারকারীগুলোকে খুঁজে বের করার জন্য আপনি আউটপুটটি সাজাতে পারেন:
# Sort by private clean + private dirty memory
adb shell showmap <pid> | awk '{print $6+$7, $0}' | sort -rn | head -n 10
নমুনা আউটপুট:
virtual shared shared private private Anon Shmem File Shared Private
size RSS PSS clean dirty clean dirty swap swapPSS HugePages PmdMapped PmdMapped Hugetlb Hugetlb Locked # object
-------- -------- -------- -------- -------- -------- -------- -------- -------- --------- --------- --------- -------- -------- -------- ---- ------------------------------
2776 18176 5784 2823 0 3008 308 2468 4700 4700 0 0 0 0 0 0 47 [anon:scudo:primary]
560 952 876 657 316 0 560 0 12 12 0 0 0 0 0 0 8 /data/app/.../base.apk
448 393216 448 448 0 0 0 448 0 0 0 0 0 0 0 0 2 [anon:dalvik-main space]
...
হাতে-কলমে অনুশীলন: শোম্যাপের সাহায্যে গভীরভাবে জানুন
নির্দিষ্ট মেমরি ম্যাপিং শনাক্ত করার এবং ক্লিন ও ডার্টি মেমরির মধ্যে পার্থক্য করার পদ্ধতি শিখুন।
- Mmap Clean Memory : MemoryLab অ্যাপে থাকা Mmap Clean Anon Memory (10MB) বাটনটিতে একবার ট্যাপ করুন।
প্রসেস আইডি জানুন : অ্যাপটির UI-তে এর PID দেখানো হয়। আপনি এই কমান্ডটি ব্যবহার করেও এটি খুঁজে পেতে পারেন:
adb shell pidof com.android.memorylabshowmap দিয়ে পরিদর্শন করুন :
# Replace <PID> with the actual process ID from the previous step adb shell showmap <PID> | grep "memorylab-clean"ম্যাপিংটি শনাক্ত করুন : আপনি
[anon:memorylab-clean]লেবেলযুক্ত একটি অ্যানোনিমাস ম্যাপিং দেখতে পাবেন, যার ভার্চুয়াল সাইজ হবে ঠিক ১০২৪০ KB। লক্ষ্য করুন যে, এই ম্যাপটির প্রাইভেট ডার্টি ভ্যালু সম্ভবত ০। এটি একটি "ক্লিন" অ্যানোনিমাস মেমরি, কারণ আমরা ভার্চুয়াল স্পেসটি রিজার্ভ করার জন্যmmapব্যবহার করেছি কিন্তু এখনও এতে কিছু লিখিনি (ফলে প্রকৃতপক্ষে কোনো ফিজিক্যাল র্যাম ব্যবহৃত হয়নি)।নেটিভ হিপ তুলনা : এটিকে
[anon:scudo:primary]ম্যাপিংগুলোর সাথে তুলনা করুন, যাmeminfoঅনুশীলনের ধাপ ৫-এর পরেshowmapচালালে দেখা যেত। যেহেতু ঐ ১ জিবি নেটিভ অ্যালোকেশনটি আসলে প্রতিটি পেজে লেখে, তাই ঐ পেজগুলো "ডার্টি" এবং private dirty কলামে ব্যাপকভাবে দেখা যাবে।বিশেষ পরামর্শ (বৃহৎ অবজেক্ট) :
meminfoঅনুশীলনের Java Heap অ্যালোকেশনগুলো লক্ষ্য করুন। যেহেতু এগুলো 10MB বাইটের অ্যারে, তাইshowmapএ এগুলো সম্ভবত[anon:dalvik-free list large object space]হিসেবে দেখা যাবে। Android Runtime (ART) মূল হিপে ফ্র্যাগমেন্টেশন এড়ানোর জন্য 12KB-এর চেয়ে বড় অবজেক্টগুলোকে একটি আলাদা Large Object Space (LOS)-এ রাখে।
প্রোকস্ট্যাটস
meminfo একটি নির্দিষ্ট সময়ের চিত্র প্রদান করে, অন্যদিকে procstats পর্যায়ক্রমে চলমান সমস্ত অ্যাপ্লিকেশনের অবস্থা এবং মেমরি ব্যবহারের নমুনা সংগ্রহ করে ঐতিহাসিক ডেটা সরবরাহ করে। দীর্ঘমেয়াদী মেমরির স্বাস্থ্য নিরীক্ষণের জন্য এটিই প্রধান টুল এবং অ্যান্ড্রয়েড সেটিংসে মেমরি ব্যবহারের রিপোর্টিং এর মাধ্যমেই পরিচালিত হয়।
# View stats for the last 3 hours
adb shell dumpsys procstats --hours 3
রাজ্যগুলি বোঝা
procstats এর আউটপুট বেশ জটিল হতে পারে। এর সবচেয়ে গুরুত্বপূর্ণ অংশ হলো প্রতিটি প্রসেস স্টেটের পাশে বন্ধনীতে থাকা মেট্রিকগুলো:
Top: 100% (54MB-64MB-67MB / 49MB-58MB-61MB / 110MB-120MB-130MB over 4)
ফর্ম্যাটটি হলো: (% স্টেটে কাটানো সময়) (স্যাম্পল অনুযায়ী minPss-avgPss-maxPss / minUss-avgUss-maxUss / minRss-avgRss-maxRss)
- Pss (প্রোপোরশনাল সেট সাইজ) : শেয়ার্ড মেমরি প্রসেসগুলোর মধ্যে আনুপাতিকভাবে ভাগ করা হয়।
- Uss (ইউনিক সেট সাইজ) : শুধুমাত্র এই প্রসেস দ্বারা ব্যবহৃত মেমরি (প্রাইভেট ক্লিন + প্রাইভেট ডার্টি-এর সমতুল্য)।
- আরএসএস (রেসিডেন্ট সেট সাইজ) : ব্যবহৃত মোট ফিজিক্যাল মেমরি, যার মধ্যে সমস্ত শেয়ার্ড পেজ অন্তর্ভুক্ত থাকে (যা প্রয়োজনের চেয়ে বেশি দেখানোর প্রবণতা থাকে)।
কেন এটি গুরুত্বপূর্ণ:
- স্থিতিশীল অ্যাপ : সর্বনিম্ন/গড়/সর্বোচ্চ মানগুলো কাছাকাছি।
- মেমোরি লিক : সর্বোচ্চ মান সর্বনিম্ন মানের চেয়ে উল্লেখযোগ্যভাবে বেশি, এবং স্যাম্পল সংখ্যা বাড়ার সাথে সাথে সময়ের সাথে গড়ও ধীরে ধীরে বাড়তে থাকে।
- স্পাইকি ইউসেজ : সর্বোচ্চ ব্যবহার গড়ের চেয়ে অনেক বেশি, যা ক্ষণস্থায়ী ভারী অপারেশন (যেমন ইমেজ প্রসেসিং) নির্দেশ করে, যা ভুল সময়ে ঘটলে OOM (আউট অফ মেমরি) ঘটাতে পারে।
প্রক্রিয়া অবস্থা
procstats বিভিন্ন রাজ্য জুড়ে অ্যাপগুলির তথ্য ট্র্যাক করে (যা প্রায়শই সংক্ষেপে লেখা হয়):
- স্থায়ী : গুরুত্বপূর্ণ সিস্টেম প্রসেস যা সর্বদা চলমান থাকে।
- শীর্ষে : অ্যাপটি বর্তমানে অগ্রভাগে রয়েছে এবং ব্যবহারকারীর কাছে দৃশ্যমান।
- ImpFg (গুরুত্বপূর্ণ ফোরগ্রাউন্ড): জরুরি ব্যাকগ্রাউন্ড প্রসেস (যেমন IME) অথবা ফোরগ্রাউন্ড সার্ভিসযুক্ত অ্যাপ।
- ImpBg (গুরুত্বপূর্ণ ব্যাকগ্রাউন্ড): ব্যাকগ্রাউন্ড প্রসেস যা সিস্টেমের জন্য গুরুত্বপূর্ণ বলে বিবেচিত হয়।
- Fgs / BFgs : ফোরগ্রাউন্ড সার্ভিস বা বাউন্ড ফোরগ্রাউন্ড সার্ভিস।
- Service / ServRst : ব্যাকগ্রাউন্ড সার্ভিস অথবা যে সার্ভিসগুলো বর্তমানে পুনরায় চালু হচ্ছে।
- ক্যাশড / লাস্টঅ্যাক্ট : যে অ্যাপগুলো দ্রুত রিস্টার্টের জন্য ব্যাকগ্রাউন্ডে ক্যাশ হয়ে থাকে। সিস্টেম থেকে এগুলো নিরাপদে বন্ধ করা যায়।
ডিভাইসের মেমরির অবস্থা এবং রান টাইম পরিসংখ্যান
procstats আরও ট্র্যাক করে যে পুরো ডিভাইসটি কতক্ষণ মেমোরি চাপের মধ্যে ছিল। Run time Stats বিভাগটি দেখুন:
Run time Stats:
SOff/Norm: +1h10m15s
SOn/Norm: +15m20s
Low: +2m10s
Crit: +45s
- SOff / SOn : স্ক্রিন বন্ধ বনাম স্ক্রিন চালু।
- নর্ম / মড / লো / ক্রিট : স্মৃতির উপর চাপের মাত্রা (স্বাভাবিক, মাঝারি, কম, সংকটজনক)।
যদি কোনো ডিভাইস দীর্ঘ সময় ধরে Low বা Crit অবস্থায় থাকে, তবে ডিভাইসটি ধীরগতির মনে হবে, কারণ কার্নেল আগ্রাসীভাবে মেমরি পুনরুদ্ধার করে এবং Low Memory Killer (LMK) ব্যাকগ্রাউন্ড প্রসেসগুলো বন্ধ করে দিতে শুরু করে। এরপর আপনি প্যাকেজ-ভিত্তিক পরিসংখ্যান দেখে নিতে পারেন যে, ডিভাইসটি এই চাপযুক্ত অবস্থায় থাকাকালীন নির্দিষ্টভাবে কোন অ্যাপগুলো বেশি মেমরি ব্যবহার করছে।
← ধারণাসমূহ | ↑ উপরে | জাভা →