WebView মেমরি ম্যানেজ ও ডায়াগনসিস করা

আপনার Android অ্যাপে ওয়েব কন্টেন্ট রেন্ডার করার জন্য WebView একাধিক প্রসেস জুড়ে নেটিভ কোড রান করে। WebView ইনস্ট্যান্স ম্যানেজ না করলে মেমরি লিক, আউট-অফ-মেমরি (OOM) ক্র্যাশ এবং অ্যাপ পারফর্ম্যান্স খারাপ হওয়ার মতো সমস্যা হতে পারে।

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

WebView মেমরি আর্কিটেকচার বোঝা

WebView মেমরি কার্যকরভাবে ম্যানেজ করতে, Android কীভাবে ওয়েব কন্টেন্টের জন্য রিসোর্স বরাদ্দ করে তা বুঝুন:

  • মাল্টি-প্রসেস এক্সিকিউশন: Android 8.0 (API লেভেল ২৬) এবং তার পরবর্তী ভার্সনে, WebView একাধিক প্রসেস জুড়ে আপনার অ্যাপের মূল ফাংশন থেকে ওয়েব কন্টেন্ট আলাদা করে (কম-RAM ডিভাইসে, এটি একটি একক প্রসেসে ফিরে যেতে পারে):

    • হোস্ট (ব্রাউজার) প্রসেস: অ্যাপের মূল প্রসেস যেখানে আপনার Activity এবং Java বা Kotlin কোড রান করে।
    • আইসোলেটেড রেন্ডারার প্রসেস: একটি আলাদা স্যান্ডবক্সড প্রসেস (SandboxedProcessService) যা HTML ও CSS পার্স করে, জাভাস্ক্রিপ্ট এক্সিকিউট করে এবং ওয়েব পেজ রেন্ডার করে।
  • নেটিভ মেমরি ফুটপ্রিন্ট: রেন্ডার করা গ্রাফিক্স, DOM ট্রি ও জাভাস্ক্রিপ্ট রানটাইম মেমরি সহ বেশিরভাগ WebView মেমরি নেটিভ মেমরিতে অ্যালোকেট করা হয়, জাভা হিপে নয়। Java হিপ ডাম্প (.hprof) শুধুমাত্র একটি লাইটওয়েট Java র‍্যাপার অবজেক্ট দেখায় এবং ওয়েব কন্টেন্টের মাধ্যমে ব্যবহৃত আসল মেমরি ক্যাপচার করে না।

  • নেটিভ মেমরির সিস্টেম ইমপ্যাক্ট: Java হিপ অ্যালোকেশনের মতো নয়, যা অ্যাপের maxHeap সীমা দ্বারা ক্যাপ করা হয় এবং OutOfMemoryError-এর সাথে দ্রুত ব্যর্থ হয়, নেটিভ মেমরি নীরবে গিগাবাইট পর্যন্ত বাড়তে পারে। যেহেতু রিলিজ না করা নেটিভ মেমরি ফিজিক্যাল RAM এবং সোয়াপ স্পেস (zRAM) পূরণ করে, তাই Android-এর লো মেমরি কিলার (LMK) মেমরি রিক্লেম করার জন্য ব্যাকগ্রাউন্ড প্রসেস বন্ধ করা শুরু করে। এটি ফোরগ্রাউন্ড অ্যাপ বন্ধ করার আগে ডিভাইসের সামগ্রিক মাল্টিটাস্কিং ক্ষমতা কমিয়ে দেয়।

WebView লাইফসাইকেল ম্যানেজ করা

মেমরি লিক আটকানোর জন্য সঠিক লাইফসাইকেল ম্যানেজমেন্ট অত্যন্ত গুরুত্বপূর্ণ। সাধারণত অনেকেই মনে করেন যে লেআউট থেকে WebView সরিয়ে দিলে বা Activity অটোমেটিক শেষ হতে দিলে মেমরি খালি হয়ে যায়।

Java কনটেক্সট রেফারেন্স এবং নেটিভ রেন্ডার রিসোর্স, দুটিরই সম্পূর্ণ ক্লিনআপ নিশ্চিত করতে, আপনাকে অবশ্যই আপনার হোস্ট কম্পোনেন্টের লাইফসাইকেলে (যেমন onDestroy()) একটি টিয়ারডাউন সিকোয়েন্স স্পষ্টভাবে সাজাতে হবে, অ্যাক্টিভ পৃষ্ঠা এক্সিকিউশন বন্ধ করতে হবে, ভিউকে তার কন্টেনার থেকে আলাদা করতে হবে এবং নেটিভ বাইন্ডিং রিলিজ করতে হবে।

WebView ইনস্ট্যান্স ক্লিন-আপ করুন

আপনার Activity বা Fragment নষ্ট হয়ে গেলে, ক্লিন শাটডাউন ও রিসোর্স রিলিজ নিশ্চিত করতে, নিম্নলিখিত ধাপগুলি অনুসরণ করুন:

  1. WebView-কে তার পেরেন্ট কন্টেনার (ViewGroup) থেকে সরিয়ে দিন।
  2. অ্যাক্টিভ লোডিং বন্ধ করে নেভিগেশন ইতিহাস মুছে দিন।
  3. destroy()-এ কল করুন।
  4. null-এর রেফারেন্স মুছে দিন।

নিম্নলিখিত উদাহরণ থেকে বোঝা যাবে যে কীভাবে WebView সঠিকভাবে ক্লিন-আপ করতে হয়:

Kotlin

override fun onDestroy() {
    myWebView?.let {
        // Remove the WebView from its parent ViewGroup.
        (it.parent as? ViewGroup)?.removeView(it)
        // Stop active loading and clear history.
        it.stopLoading()
        it.clearHistory()
        // Destroy the instance.
        it.destroy()
    }
    myWebView = null
    super.onDestroy()
}

জাভা

@Override
protected void onDestroy() {
    if (myWebView != null) {
        // Remove the WebView from its parent ViewGroup.
        if (myWebView.getParent() instanceof ViewGroup) {
            ((ViewGroup) myWebView.getParent()).removeView(myWebView);
        }
        // Stop active loading and clear history.
        myWebView.stopLoading();
        myWebView.clearHistory();
        // Destroy the instance.
        myWebView.destroy();
    }
    myWebView = null;
    super.onDestroy();
}

পোস্ট-ডিস্ট্রাকশন মেমরি সম্পর্কে বোঝা

আপনি destroy() কল করলে, সিস্টেম Activity কন্টেক্সট রিলিজ করে, ভিউ হায়ারার্কি ক্লিন-আপ করে এবং ওয়েব ব্যাকগ্রাউন্ডের কাজ বন্ধ করে দেয়। তবে, আপনি লক্ষ্য করতে পারেন যে প্রসেসের ফিজিক্যাল মেমরি (রেসিডেন্ট সেট সাইজ) অবিলম্বে তার প্রি-WebView বেসলাইনে নেমে আসে না।

এই আচরণ স্বাভাবিক। নেটিভ রানটাইম ক্যাশে, শেয়ার করা লাইব্রেরি এবং বরাদ্দ করা মেমরি পৃষ্ঠা প্রসেসে থেকে যায় যতক্ষণ না অপারেটিং সিস্টেম সেগুলি পুনরুদ্ধার করে বা প্রসেসটি শেষ হয়। destroy()-এর প্রাথমিক লক্ষ্য হল ব্যবহারকারীরা যখন ওয়েব-চালিত স্ক্রিনে নেভিগেট করেন তখন ক্রমবর্ধমান Activity মেমরি লিক প্রতিরোধ করা।

গুরুত্বপূর্ণ ডিবাগিং মেট্রিক

WebView মেমরি ব্যবহার বিশ্লেষণ করার সময়, নিম্নলিখিত মেট্রিকগুলিতে ফোকাস করুন:

  • রেসিডেন্ট সেট সাইজ (RSS): প্রসেসে ম্যাপ করা মোট ফিজিক্যাল RAM, যার মধ্যে শেয়ার করা কোড ও লাইব্রেরি (Android Studio Profiler-এ মোট হিসেবে লেবেল করা) অন্তর্ভুক্ত।

  • অ্যানোনিমাস RSS (RssAnon): সরাসরি প্রসেসের মাধ্যমে বরাদ্দ করা মেমরি যা ডিস্কের কোনও ফাইল দ্বারা ব্যাক-আপ করা হয় না (যেমন নেটিভ হিপ এবং জাভাস্ক্রিপ্ট রানটাইম অ্যালোকেশন)। এটি আপনার ওয়েব কন্টেন্টের প্রাথমিক মেমরি খরচ দেখায় (Android Studio Profiler-এ অ্যালোকেট করা হিসেবে লেবেল করা)।

  • প্রাইভেট মেমরি ফুটপ্রিন্ট (PMF): Anonymous RSS ও সোয়াপের (zRAM) যোগফল। PMF আপনার অ্যাপের মাধ্যমে সিস্টেমে আরোপিত প্রকৃত আনইভিক্টেবল মেমরি বার্ডেন প্রতিফলিত করে।

  • ব্রাউজার PMF বনাম রেন্ডারার PMF: আপনার অ্যাপের মূল প্রসেস দ্বারা ব্যবহৃত মেমরি বনাম আইসোলেটেড রেন্ডারার প্রসেস দ্বারা ব্যবহৃত মেমরি। ভারী ওয়েব কন্টেন্ট মূলত রেন্ডারার প্রসেসে স্পাইক ঘটায়।

  • লাইভ অবজেক্টের সংখ্যা (WebViews, Activities, Views): মেমরিতে থাকা অ্যাক্টিভ UI, প্রসঙ্গ ও WebView ইনস্ট্যান্সের সংখ্যা। এগুলি ট্র্যাক করলে বোঝা যায় যে মেমরি বৃদ্ধি রিটেন করা Java রেফারেন্স নাকি শুধুমাত্র নেটিভ অ্যালোকেশনের কারণে হয়েছে।

  • প্রাইভেট অন্যান্য এবং নেটিভ হিপ: dumpsys meminfo-এ, নেটিভ C/C++ অ্যালোকেশন এবং কাস্টম মেমরি ম্যাপিং (যেমন Chromium PartitionAlloc বা এম্বেড করা জাভাস্ক্রিপ্ট রানটাইম হিপ) জাভা হিপের পরিবর্তে নেটিভ হিপ এবং প্রাইভেট অন্যান্য বিকল্পের অধীনে দেখা যায়।

প্রসেস মেমরি কাউন্টার ও তার বিভাগ সম্পর্কে আরও জানতে, প্রসেস মেমরি গ্লসারি দেখুন।

ব্যবহারিক ডায়াগনস্টিক ওয়ার্কফ্লো

যেহেতু WebView একাধিক প্রসেস জুড়ে কাজ করে এবং নেটিভ মেমরি বরাদ্দ করে, তাই এর ফুটপ্রিন্ট পরীক্ষা করতে নিম্নলিখিত টুল এবং কৌশলগুলি ব্যবহার করুন:

প্রোফাইলিং ও ডায়াগনস্টিক টুল

মেমরি অ্যালোকেশন পরীক্ষা করতে এবং লিক ডায়াগনসিস করতে, নিম্নলিখিত টুল ব্যবহার করুন:

  • Android Studio মেমরি প্রোফাইলার: মেমরি প্রোফাইলার ব্যবহার করে নেটিভ অ্যালোকেশন ভিজ্যুয়ালাইজ করুন, সময়ের সাথে সাথে মেমরি ক্যাটেগরি ট্র্যাক করুন এবং স্ক্রিন ট্রানজিশন জুড়ে Activity লিক শনাক্ত করুন।

  • Perfetto-র মাধ্যমে মেমরি ট্র্যাক করা: সামগ্রিক মেমরি বৃদ্ধি পর্যবেক্ষণ করতে সিস্টেম-লেভেল মেমরি কাউন্টার (যেমন RSS এবং Anonymous RSS) রেকর্ড করতে Perfetto ব্যবহার করুন। মনে রাখবেন যে WebView নেটিভ ইঞ্জিন অ্যালোকেশন Perfetto-এর হিপ প্রোফাইলিং টুলে কলস্ট্যাক তৈরি করে না। ওয়েব কন্টেন্টের মধ্যে জাভাস্ক্রিপ্ট হিপ স্ন্যাপশট ও DOM অ্যালোকেশন পরীক্ষা করতে Chrome DevTools ব্যবহার করুন।

লাইভ অবজেক্টের সংখ্যা দেখুন

মেমরি বৃদ্ধি রিটেন করা Java ফ্রেমওয়ার্ক অবজেক্ট (যেমন UI কম্পোনেন্ট) নাকি নেটিভ অ্যালোকেশনের কারণে হচ্ছে তা নির্ধারণ করতে, dumpsys meminfo-এর Objects বিভাগটি দেখুন:

adb shell dumpsys meminfo -a <var>PACKAGE_NAME</var> | grep -A 10 "Objects"

আউটপুটে লাইভ অবজেক্টের সংখ্যা দেখানো হয়:

 Objects
               Views:     142         ViewRootImpl:        1
         AppContexts:       3           Activities:        1
              Assets:      12        AssetManagers:        0
       Local Binders:      32        Proxy Binders:       45
       Parcel memory:      15         Parcel count:       30
    Death Recipients:       2             WebViews:        1

এই বিভাগে অ্যাক্টিভ ফ্রেমওয়ার্ক অবজেক্ট, IPC হ্যান্ডেল ও পার্সেল অ্যালোকেশনের সংখ্যা দেখানো হয়। WebView ডায়াগনস্টিকসের জন্য, প্রধানত Activities এবং WebViews-এর উপর ফোকাস করুন।

টার্গেট ব্যবহারকারীর ইন্টার‍্যাকশন (যেমন, ওয়েব স্ক্রিন খোলা ও বন্ধ করা) বারবার পারফর্ম করুন এবং গণনা তুলনা করুন:

  • ইনস্ট্যান্স লিক: প্রতিটি নেভিগেশনে WebViews বা Activities বৃদ্ধি পেলে এবং বেসলাইনে ফিরে না আসলে, আপনার অ্যাপ Java WebView ইনস্ট্যান্স বা হোস্ট Activity লিক করছে (যেমন, ViewGroup.removeView() বা রিটেন করা লিসেনার রেফারেন্স না থাকার কারণে)। কারণ একটি লিক হওয়া Activity মেমরিতে তার সম্পূর্ণ ভিউ ট্রি এবং ডিকোড করা ইমেজ রিসোর্স পিন করে, বারবার ভিজিট করলে জাভা হিপ দ্রুত শেষ হয়ে যাবে এবং এর ফলে OutOfMemoryError ক্র্যাশ হবে।

  • নেটিভ বা DOM লিক: যদি WebViews এবং Activities অপরিবর্তিত থাকে এবং মোট প্রসেস RSS ও ব্যক্তিগত অন্যান্য ক্রমাগত বাড়তে থাকে, তাহলে রিলিজ না করা নেটিভ রিসোর্স, DOM এলিমেন্ট বা JavaScript ইঞ্জিন বাইন্ডিং থেকে লিক হয়। এইসব অ্যালোকেশন নেটিভ মেমরিতে থাকে এবং ART গার্বেজ কালেক্টরকে বাইপাস করে, তাই স্ট্যান্ডার্ড জাভা লিক শনাক্তকরণ টুলের কাছে এগুলি অদৃশ্য থাকে এবং অপারেটিং সিস্টেম অ্যাপটি বন্ধ না করা পর্যন্ত জমা হতে থাকে।

CLI ব্যবহার করে আইসোলেটেড রেন্ডারার প্রসেসের প্রোফাইল তৈরি করুন

আপনার অ্যাপের প্যাকেজের নাম দিয়ে dumpsys meminfo রান করলে, শুধু প্রধান হোস্ট প্রসেসের জন্য মেমরি আউটপুট পাওয়া যায়। আইসোলেটেড রেন্ডারার প্রসেস পরীক্ষা করতে, যেখানে ওয়েব পেজ রেন্ডার করা হয়:

  1. আইসোলেটেড রেন্ডারার পরিষেবার প্রসেস আইডি (PID) খুঁজুন:

    adb shell dumpsys activity processes <var>PACKAGE_NAME</var> | grep "Isolated.*SandboxedProcessService"

    আউটপুটে আইসোলেট করা প্রসেস রেকর্ড ও তার PID RENDERER_PID (যেমন, 22155) দেখা যায়:

    Isolated #5: ProcessRecord{... 22155:com.google.android.webview.debug:sandboxed_process0:...}
    
  2. PID ব্যবহার করে রেন্ডারার প্রসেসের মেমরি ব্রেকডাউন দেখুন:

    adb shell dumpsys meminfo <var>RENDERER_PID</var>
  3. ব্রাউজার-সাইড ফুটপ্রিন্ট মূল্যায়ন করতে হোস্ট অ্যাপ প্রসেসটি পরীক্ষা করুন:

    adb shell dumpsys meminfo <var>PACKAGE_NAME</var>

মেমরি ম্যাপ ও অ্যালোকেশন পরীক্ষা করুন

কোন নেটিভ সাবসিস্টেম বা অ্যালোকেটর বেনামী মেমরি দখল করে তা দেখতে, প্রসেস মেমরি ম্যাপগুলি পরীক্ষা করুন:

adb shell "cat /proc/$(pidof <var>PACKAGE_NAME</var>)/maps" | grep "anon:"

নিচের সারণীতে সাধারণ বেনামী মেমরি ট্যাগ এবং মেমরি বৃদ্ধির সাথে তাদের প্রাসঙ্গিকতা তালিকাভুক্ত করা হয়েছে:

মেমরি ট্যাগ সাবসিস্টেম অ্যাপ ও ওয়েব কন্টেন্টের সাথে প্রাসঙ্গিকতা মেমরি বাড়ার সাধারণ কারণ কী?
[anon:partition_alloc] Chromium PartitionAlloc WebView-এ DOM ট্রি, রেন্ডারিং বাফার, V8 জাভাস্ক্রিপ্ট হিপ ও WebAssembly এক্সিকিউশনের জন্য অ্যালোকেশন। হ্যাঁ (বেশি): ভারী ওয়েব পেজ, মিডিয়া-রিচ DOM লোড করা অথবা বাতিল করা WebView ইনস্ট্যান্সে destroy() কল করতে না পারা সরাসরি এই ট্যাগকে ইনফ্লেট করে।
[anon:scudo...] বা [anon:libc_malloc] Android নেটিভ হিপ অ্যালোকেটর (Scudo / jemalloc) NDK লাইব্রেরি, JNI ব্রিজ ও নেটিভ গ্রাফিক্স পাইপলাইনের মাধ্যমে ব্যবহৃত সাধারণ C/C++ নেটিভ অ্যালোকেশন। হ্যাঁ (মাঝারি থেকে বেশি): নেটিভ JNI র‍্যাপার বা থার্ড-পার্টি C++ ডিপেন্ডেন্সি নেভিগেশন জুড়ে রিলিজ না করা অ্যালোকেশন ধরে রাখলে মেমরি ব্যবহার বৃদ্ধি পায়।
[anon:...] (যেমন, [anon:quickjs_heap...]) কাস্টম স্ক্রিপ্টিং বা নেটিভ রানটাইম এম্বেড করা জাভাস্ক্রিপ্ট ইঞ্জিন, কাস্টম WebAssembly রানটাইম বা কাস্টম নেটিভ বাফার পুল। হ্যাঁ (প্রসঙ্গ-নির্ভর): হাইব্রিড অ্যাপে এটি সাধারণ ঘটনা, যা নেটিভ ভিউয়ের পাশাপাশি স্ক্রিপ্টিং ইঞ্জিন এক্সিকিউট করে এবং রানটাইম বাইন্ডিং ক্লিন-আপ করতে ব্যর্থ হয়।

ইন-অ্যাপ মেমরি API-এর সীমাবদ্ধতা

অ্যাপ-মধ্যস্থ মেমরি API (যেমন Debug.getMemoryInfo বা ActivityManager.getProcessMemoryInfo) শুধুমাত্র কলিং প্রসেস পরিমাপ করে। মাল্টি-প্রসেস মোডে, এই APIগুলি আইসোলেটেড রেন্ডারার প্রসেসের মাধ্যমে ব্যবহৃত মেমরি ক্যাপচার করতে পারে না। মোট মেমরির সঠিক মূল্যায়ন করতে, dumpsys meminfo, Perfetto বা Android Studio Profiler-এর মতো সিস্টেম টুলের উপর নির্ভর করুন।

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

WebView-এর সাথে বারবার ইন্টার‍্যাক্ট করার সময় (যেমন, ওয়েব লিঙ্ক খোলা বা ওয়েব-পাওয়ার্ড ফিড নেভিগেট করা) মেমরি ব্যবহারের পরিমাণ ব্যাখ্যাতীতভাবে বেড়ে যাওয়ার কারণ ডায়াগনসিস করার সময়, নিম্নলিখিত ট্রায়াজ ওয়ার্কফ্লো ব্যবহার করে দেখুন যে লিকটি জাভা লেয়ারে নাকি নেটিভ ইঞ্জিনে হচ্ছে:

  1. লিকের ধরন আলাদা করুন (জাভা বনাম নেটিভ): ব্যবহারকারীর বারবার ট্রানজিশনের (যেমন, ওয়েব আর্টিকেল খোলা ও বন্ধ করা অথবা ফিডের মধ্যে সোয়াইপ করা) আগে ও পরে dumpsys meminfo -a <var>PACKAGE_NAME</var> | grep -A 10 "Objects" রান করুন।

    • পর্যবেক্ষণ: Activities এবং WebViews-এর সংখ্যা স্থির থাকলে (যেমন, ১–২টি অ্যাক্টিভ ইনস্ট্যান্স), অ্যাপটি Activity কনটেক্সট বা Java WebView ইনস্ট্যান্স লিক করছে না।
  2. ইন্টার‍্যাকশন জুড়ে মেমরি ডেল্টা পরিমাপ করুন (টাইম-সিরিজ ট্র্যাকিং): ট্রানজিশন প্রতি অ্যালোকেশন রেট গণনা করতে একাধিক ব্যবহারকারীর ইন্টার‍্যাকশন জুড়ে dumpsys meminfo স্ন্যাপশট ক্যাপচার করুন:

    • পর্যবেক্ষণ: Java হিপ ক্যাপ করা এবং সুস্থ থাকে (ব্যবহারের সময় স্পাইক করে এবং আবর্জনা সংগ্রহের পরে কমে যায়), কিন্তু ব্যক্তিগত অন্যান্য এবং নেটিভ হিপ ট্রানজিশন প্রতি কয়েক মেগাবাইট করে ক্রমাগত বৃদ্ধি পায়। এটি প্রমাণ করে যে লিকটি সম্পূর্ণভাবে ART রানটাইমের বাইরে নেটিভ মেমরিতে রয়েছে। স্ট্যান্ডার্ড Java হিপ ডাম্প (.hprof) কোনও সমস্যা দেখাবে না।
  3. বেনামী মেমরি ম্যাপ পরীক্ষা করা: ADB ব্যবহার করে প্রসেস মেমরি ম্যাপ পরীক্ষা করা (মেমরি ম্যাপ ও বরাদ্দ পরীক্ষা করা দেখুন):

    adb shell "cat /proc/$(pidof <var>PACKAGE_NAME</var>)/maps" | grep "anon:"
    • পর্যবেক্ষণ: মেমরি বৃদ্ধি [anon:partition_alloc] বা এম্বেড করা স্ক্রিপ্টিং ইঞ্জিন হিপে কেন্দ্রীভূত হয়, সাথে JNI গ্লোবাল রেফারেন্সে ধীরে ধীরে বৃদ্ধি পায়। এটি ইঙ্গিত করে যে Java ভিউ পরিবর্তন করা হলেও, অন্তর্নিহিত নেটিভ পৃষ্ঠা অবজেক্ট বা JavaScript বাইন্ডিং রিলিজ করা হয়নি।
  4. প্রতিকার:

    • নিশ্চিত করুন যে প্রতিটি রিসাইকেল করা বা বাতিল করা WebView স্পষ্টভাবে অ্যাক্টিভ স্ক্রিপ্ট (stopLoading()) বন্ধ করে, ইতিহাস মুছে দেয় এবং destroy() কল করে।
    • বাতিল করা ভিউয়ের সাথে যুক্ত কাস্টম JavaScript ব্রিজ কলব্যাক বা JNI গ্লোবাল রেফারেন্স মুছে দিন।
    • নেভিগেশন ট্রানজিশনের পরে Private Other এবং প্রসেস RSS স্থিতিশীল হয়েছে কিনা তা কনফার্ম করুন।

অতিরিক্ত রিসোর্স

মেমরি ও WebView পারফর্ম্যান্স ডিবাগ ও প্রোফাইল করা সম্পর্কে আরও জানতে, নিম্নলিখিত রিসোর্স দেখুন: