দ্রুত মূল্যায়ন সরঞ্জাম

যখন স্মৃতিশক্তির ব্যবহার খতিয়ে দেখার প্রয়োজন হয়, তখন কোন ধরনের স্মৃতি সবচেয়ে গুরুত্বপূর্ণ তা শনাক্ত করতে উচ্চ-স্তরের মূল্যায়ন সরঞ্জাম দিয়ে শুরু করুন।

ডাম্পসিস মেমইনফো

কোনো অ্যাপ্লিকেশনের মেমরি ব্যবহারের একটি সার্বিক ধারণা পাওয়ার সবচেয়ে প্রচলিত উপায় হলো 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 তে প্রদর্শিত হয়।

  1. অ্যাপটি চালু করুন :

    adb shell am start -W -n com.android.memorylab/.MainActivity
    
  2. বেসলাইন মেমরি পরীক্ষা করুন :

    adb shell dumpsys meminfo -s com.android.memorylab
    

    ( -s ফ্ল্যাগটি মেমরি ক্যাটাগরিগুলোর একটি সংক্ষিপ্ত ও সারগর্ভ সারসংক্ষেপ প্রদান করে)।

  3. জাভা মেমরি বরাদ্দ করুন : অ্যাপের মধ্যে থাকা ‘জাভা মেমরি বরাদ্দ করুন (10MB)’ বোতামটি ৩ বার ট্যাপ করুন।

  4. পরিবর্তনটি লক্ষ্য করুন : আবার meminfo -s চালান। আপনি দেখবেন যে জাভা হিপ ভ্যালু প্রায় ৩০,০০০ কিলোবাইট (৩০ মেগাবাইট) বৃদ্ধি পেয়েছে।

  5. নেটিভ মেমরি বরাদ্দ করুন : 'নেটিভ মেমরি বরাদ্দ করুন (১জিবি অসংকোচনীয়)' বোতামটি একবার ট্যাপ করুন।

  6. পরিবর্তনটি লক্ষ্য করুন : আবার 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]
...

হাতে-কলমে অনুশীলন: শোম্যাপের সাহায্যে গভীরভাবে জানুন

নির্দিষ্ট মেমরি ম্যাপিং শনাক্ত করার এবং ক্লিন ও ডার্টি মেমরির মধ্যে পার্থক্য করার পদ্ধতি শিখুন।

  1. Mmap Clean Memory : MemoryLab অ্যাপে থাকা Mmap Clean Anon Memory (10MB) বাটনটিতে একবার ট্যাপ করুন।
  2. প্রসেস আইডি জানুন : অ্যাপটির UI-তে এর PID দেখানো হয়। আপনি এই কমান্ডটি ব্যবহার করেও এটি খুঁজে পেতে পারেন:

    adb shell pidof com.android.memorylab
    
  3. showmap দিয়ে পরিদর্শন করুন :

    # Replace <PID> with the actual process ID from the previous step
    adb shell showmap <PID> | grep "memorylab-clean"
    
  4. ম্যাপিংটি শনাক্ত করুন : আপনি [anon:memorylab-clean] লেবেলযুক্ত একটি অ্যানোনিমাস ম্যাপিং দেখতে পাবেন, যার ভার্চুয়াল সাইজ হবে ঠিক ১০২৪০ KB। লক্ষ্য করুন যে, এই ম্যাপটির প্রাইভেট ডার্টি ভ্যালু সম্ভবত ০। এটি একটি "ক্লিন" অ্যানোনিমাস মেমরি, কারণ আমরা ভার্চুয়াল স্পেসটি রিজার্ভ করার জন্য mmap ব্যবহার করেছি কিন্তু এখনও এতে কিছু লিখিনি (ফলে প্রকৃতপক্ষে কোনো ফিজিক্যাল র‍্যাম ব্যবহৃত হয়নি)।

  5. নেটিভ হিপ তুলনা : এটিকে [anon:scudo:primary] ম্যাপিংগুলোর সাথে তুলনা করুন, যা meminfo অনুশীলনের ধাপ ৫-এর পরে showmap চালালে দেখা যেত। যেহেতু ঐ ১ জিবি নেটিভ অ্যালোকেশনটি আসলে প্রতিটি পেজে লেখে, তাই ঐ পেজগুলো "ডার্টি" এবং private dirty কলামে ব্যাপকভাবে দেখা যাবে।

  6. বিশেষ পরামর্শ (বৃহৎ অবজেক্ট) : 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) ব্যাকগ্রাউন্ড প্রসেসগুলো বন্ধ করে দিতে শুরু করে। এরপর আপনি প্যাকেজ-ভিত্তিক পরিসংখ্যান দেখে নিতে পারেন যে, ডিভাইসটি এই চাপযুক্ত অবস্থায় থাকাকালীন নির্দিষ্টভাবে কোন অ্যাপগুলো বেশি মেমরি ব্যবহার করছে।


← ধারণাসমূহ | ↑ উপরে | জাভা →