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

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

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

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

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

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

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

  • নেটিভ মেমরির কারণে সিস্টেমের উপর প্রভাব: জাভা হিপ অ্যালোকেশন অ্যাপের 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): বেনামী RSS ও সোয়াপের (zRAM) যোগফল। PMF আপনার অ্যাপের কারণে সিস্টেমের উপর পড়া প্রকৃত আনইভিক্টেবল মেমরি বার্ডেনকে প্রতিফলিত করে।

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

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

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

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

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

WebView একাধিক প্রসেস জুড়ে কাজ করে এবং নেটিভ মেমরি অ্যালোকেট করে বলে, এর ফুটপ্রিন্ট চেক করতে নিম্নলিখিত টুল ও টেকনিক ব্যবহার করুন:

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

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

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

  • Perfetto-এর মাধ্যমে মেমরি ট্র্যাক করা: সামগ্রিক মেমরি বৃদ্ধি পর্যবেক্ষণ করতে, সিস্টেম-লেভেল মেমরি কাউন্টার (যেমন RSS এবং অ্যানোনিমাস 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 মেমরিতে এর সম্পূর্ণ ভিউ ট্রি ও ডিকোড করা ইমেজ রিসোর্স পিন করে, বারবার ভিজিট করলে দ্রুত Java হিপ শেষ হয়ে যায় এবং OutOfMemoryError ক্র্যাশ হয়।

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

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 JavaScript হিপ ও 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 ইন্টার‍্যাকশনের (যেমন, ওয়েব লিঙ্ক খোলা বা ওয়েব-চালিত ফিড নেভিগেট করা) সময়, ব্যাখ্যা করা যায় না এমন মেমরি বৃদ্ধি ডায়াগনসিস করার সময়, লিকেজটি Java লেয়ারে নাকি নেটিভ ইঞ্জিনে হয়েছে তা আলাদা করতে নিম্নলিখিত ট্রায়েজ ওয়ার্কফ্লো ব্যবহার করুন:

  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 পারফর্ম্যান্স ডিবাগ ও প্রোফাইল করা সম্পর্কে আরও জানতে, নিম্নলিখিত রিসোর্স দেখুন: