WebView, आपके Android ऐप्लिकेशन में वेब कॉन्टेंट रेंडर करने के लिए, कई प्रोसेस में नेटिव कोड चलाता है. WebView इंस्टेंस को मैनेज न करने पर, मेमोरी लीक हो सकती है, मेमोरी खत्म होने (ओओएम) की वजह से ऐप्लिकेशन क्रैश हो सकता है, और ऐप्लिकेशन की परफ़ॉर्मेंस खराब हो सकती है.
इस दस्तावेज़ में, WebView मल्टी-प्रोसेस मेमोरी मॉडल के बारे में बताया गया है. साथ ही, इसमें मेमोरी लीक को रोकने के लिए, इसके लाइफ़साइकल को सही तरीके से मैनेज करने का तरीका बताया गया है. इसके अलावा, मेमोरी से जुड़ी समस्याओं का पता लगाने के लिए, व्यावहारिक वर्कफ़्लो दिए गए हैं.
WebView की मेमोरी आर्किटेक्चर को समझना
WebView मेमोरी को असरदार तरीके से मैनेज करने के लिए, यह समझें कि Android, वेब कॉन्टेंट के लिए संसाधनों को कैसे असाइन करता है:
एक से ज़्यादा प्रोसेस में काम करने की सुविधा: Android 8.0 (एपीआई लेवल 26) और इसके बाद के वर्शन पर,
WebViewवेब कॉन्टेंट को आपके ऐप्लिकेशन के मुख्य फ़ंक्शन से अलग करता है. ऐसा कई प्रोसेस में किया जाता है. कम रैम वाले डिवाइसों पर, यह सुविधा एक ही प्रोसेस में काम कर सकती है:- होस्ट (ब्राउज़र) प्रोसेस: यह मुख्य ऐप्लिकेशन प्रोसेस होती है. इसमें आपका
Activityऔर Java या Kotlin कोड चलता है. - आइसोलेटेड रेंडरर प्रोसेस: यह एक अलग सैंडबॉक्स वाली प्रोसेस (
SandboxedProcessService) होती है. यह एचटीएमएल और सीएसएस को पार्स करती है, JavaScript को एक्ज़ीक्यूट करती है, और वेब पेजों को रेंडर करती है.
- होस्ट (ब्राउज़र) प्रोसेस: यह मुख्य ऐप्लिकेशन प्रोसेस होती है. इसमें आपका
नेटिव मेमोरी फ़ुटप्रिंट: ज़्यादातर
WebViewमेमोरी, नेटिव मेमोरी में असाइन की जाती है. इसमें रेंडर किए गए ग्राफ़िक, डीओएम ट्री, और JavaScript रनटाइम मेमोरी शामिल है. यह मेमोरी, Java हीप में असाइन नहीं की जाती. Java हीप डंप (.hprof) में सिर्फ़ एक लाइटवेट Java रैपर ऑब्जेक्ट दिखता है. साथ ही, यह वेब कॉन्टेंट के लिए इस्तेमाल की गई मेमोरी को कैप्चर नहीं करता.नेटिव मेमोरी का सिस्टम पर असर: Java हीप के लिए मेमोरी का बंटवारा, ऐप्लिकेशन की
maxHeapसीमा के हिसाब से होता है. साथ ही,OutOfMemoryErrorके साथ तुरंत बंद हो जाता है. हालांकि, नेटिव मेमोरी साइलेंट मोड में गीगाबाइट तक बढ़ सकती है. जब रिलीज़ नहीं की गई नेटिव मेमोरी, फ़िज़िकल रैम और स्वैप स्पेस (zRAM) को भर देती है, तब Android का Low Memory Killer (LMK), मेमोरी को वापस पाने के लिए बैकग्राउंड प्रोसेस को बंद करना शुरू कर देता है. इससे डिवाइस पर मल्टीटास्किंग की परफ़ॉर्मेंस कम हो जाती है. इसके बाद, फ़ोरग्राउंड ऐप्लिकेशन बंद हो जाता है.
WebView की लाइफ़साइकल मैनेज करना
मेमोरी लीक को रोकने के लिए, लाइफ़साइकल को सही तरीके से मैनेज करना ज़रूरी है. आम तौर पर, लोग यह गलती करते हैं कि लेआउट से WebView को हटाने या Activity के अपने-आप बंद होने से, उसकी मेमोरी खाली हो जाती है.
Java कॉन्टेक्स्ट रेफ़रंस और नेटिव रेंडरिंग संसाधनों को पूरी तरह से हटाने के लिए, आपको अपने होस्ट कॉम्पोनेंट के लाइफ़साइकल (जैसे कि onDestroy()) में, हटाने की प्रोसेस को साफ़ तौर पर व्यवस्थित करना होगा. जैसे, चालू पेज के एक्ज़ीक्यूशन को रोकना, व्यू को उसके कंटेनर से अलग करना, और नेटिव बाइंडिंग को रिलीज़ करना.
WebView इंस्टेंस मिटाना
यह पक्का करने के लिए कि Activity या Fragment को बंद करते समय, सभी संसाधन रिलीज़ हो जाएं, यह तरीका अपनाएं:
WebViewको उसके पैरंट कंटेनर (ViewGroup) से हटाएं.- नेविगेशन के इतिहास को मिटाता है और पेज लोड होने की प्रोसेस को रोकता है.
destroy()पर कॉल करें.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() }
Java
@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 मेमोरी के इस्तेमाल का विश्लेषण करते समय, इन मेट्रिक पर फ़ोकस करें:
रेज़िडेंट सेट साइज़ (आरएसएस): प्रोसेस में मैप की गई कुल फ़िज़िकल रैम. इसमें शेयर किया गया कोड और लाइब्रेरी शामिल होती हैं. Android Studio Profiler में इसे कुल के तौर पर लेबल किया जाता है.
बिना सोर्स फ़ाइल वाली आरएसएस मेमोरी (RssAnon): यह प्रोसेस के लिए सीधे तौर पर असाइन की गई मेमोरी होती है. इसे डिस्क पर मौजूद किसी फ़ाइल से बैक अप नहीं लिया जाता. जैसे, नेटिव हीप और JavaScript रनटाइम के लिए असाइन की गई मेमोरी. इससे आपके वेब कॉन्टेंट की प्राइमरी मेमोरी की लागत का पता चलता है. Android Studio Profiler में इसे Allocated के तौर पर लेबल किया जाता है.
प्राइवेट मेमोरी फ़ुटप्रिंट (पीएमएफ़): बिना सोर्स फ़ाइल वाली आरएसएस मेमोरी और स्वैप मेमोरी (zRAM) का योग. पीएमएफ़ से पता चलता है कि आपका ऐप्लिकेशन, सिस्टम की कितनी मेमोरी का इस्तेमाल कर रहा है.
ब्राउज़र पीएमएफ़ बनाम रेंडरर पीएमएफ़: आपके ऐप्लिकेशन की मुख्य प्रोसेस ने कितनी मेमोरी इस्तेमाल की बनाम आइसोलेटेड रेंडरर प्रोसेस ने कितनी मेमोरी इस्तेमाल की. ज़्यादा डेटा इस्तेमाल करने वाले वेब कॉन्टेंट की वजह से, मुख्य तौर पर रेंडरर प्रोसेस में स्पाइक आते हैं.
लाइव ऑब्जेक्ट की संख्या (
WebViews,Activities,Views): मेमोरी में मौजूद, चालू यूज़र इंटरफ़ेस (यूआई), कॉन्टेक्स्ट, औरWebViewइंस्टेंस की संख्या. इनको ट्रैक करने से यह पता चलता है कि मेमोरी में बढ़ोतरी, बनाए रखे गए Java रेफ़रंस या सिर्फ़ नेटिव ऐप्लिकेशन के लिए किए गए असाइनमेंट की वजह से हुई है.निजी अन्य और नेटिव हीप:
dumpsys meminfoमें, नेटिव C/C++ ऐलोकेशन और कस्टम मेमोरी मैपिंग (जैसे कि ChromiumPartitionAllocया एम्बेड किया गया JavaScript रनटाइम हीप) Java हीप के बजाय नेटिव हीप और निजी अन्य के तहत दिखते हैं.
प्रोसेस मेमोरी काउंटर और उनकी कैटगरी के बारे में ज़्यादा जानने के लिए, प्रोसेस मेमोरी की शब्दावली देखें.
गड़बड़ी की जानकारी देने वाले काम के वर्कफ़्लो
WebView कई प्रोसेस पर काम करता है और नेटिव मेमोरी को असाइन करता है. इसलिए, इसके फ़ुटप्रिंट की जांच करने के लिए, इन टूल और तकनीकों का इस्तेमाल करें:
प्रोफ़ाइलिंग और डाइग्नोस्टिक टूल
मेमोरी के बंटवारे की जांच करने और मेमोरी लीक का पता लगाने के लिए, इन टूल का इस्तेमाल करें:
Android Studio का मेमोरी प्रोफ़ाइलर: मेमोरी प्रोफ़ाइलर का इस्तेमाल करके, इन कामों को पूरा करें: नेटिव ऐलोकेशन को विज़ुअलाइज़ करना, समय के साथ मेमोरी कैटगरी को ट्रैक करना, और स्क्रीन ट्रांज़िशन के दौरान
Activityलीक का पता लगाना.Perfetto की मदद से मेमोरी को ट्रैक करना: सिस्टम-लेवल के मेमोरी काउंटर (जैसे कि आरएसएस और बिना सोर्स फ़ाइल वाली आरएसएस मेमोरी) को रिकॉर्ड करने के लिए, Perfetto का इस्तेमाल करें. इससे मेमोरी के इस्तेमाल में होने वाली बढ़ोतरी को देखा जा सकता है. ध्यान दें कि
WebViewनेटिव इंजन के लिए किए गए मेमोरी असाइनमेंट, Perfetto के हीप प्रोफ़ाइलिंग टूल में कॉलस्टैक जनरेट नहीं करते. वेब कॉन्टेंट में JavaScript हीप स्नैपशॉट और डीओएम के लिए मेमोरी के बंटवारे की जांच करने के लिए, Chrome DevTools का इस्तेमाल करें.
लाइव ऑब्जेक्ट की संख्या की जांच करना
यह पता लगाने के लिए कि मेमोरी में बढ़ोतरी, बनाए रखे गए Java फ़्रेमवर्क ऑब्जेक्ट (जैसे कि यूज़र इंटरफ़ेस कॉम्पोनेंट) या नेटिव ऐलोकेशन की वजह से हुई है, Objects सेक्शन की जांच करें dumpsys meminfo:
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
इस सेक्शन में, चालू फ़्रेमवर्क ऑब्जेक्ट, आईपीसी हैंडल, और पार्सल के बंटवारे की संख्या दिखती है. WebView डाइग्नोस्टिक्स के लिए, मुख्य रूप से Activities और WebViews पर फ़ोकस करें.
उपयोगकर्ता के टारगेट इंटरैक्शन (जैसे, वेब स्क्रीन खोलना और बंद करना) को बार-बार करें और संख्या की तुलना करें:
इंस्टेंस लीक: अगर हर नेविगेशन पर
WebViewsयाActivitiesबढ़ता है और बेसलाइन पर वापस नहीं आता है, तो इसका मतलब है कि आपका ऐप्लिकेशन JavaWebViewइंस्टेंस या होस्टActivityलीक कर रहा है. उदाहरण के लिए, ऐसाViewGroup.removeView()के न होने या लिसनर के रेफ़रंस बनाए रखने की वजह से हो सकता है. लीक हुईActivity, अपने पूरे व्यू ट्री और डिकोड की गई इमेज के संसाधनों को मेमोरी में पिन करती है. इसलिए, बार-बार विज़िट करने से Java हीप तेज़ी से खत्म हो जाएगा औरOutOfMemoryErrorक्रैश हो जाएगा.नेटिव या डीओएम लीक: अगर कुल प्रोसेस आरएसएस और निजी अन्य में लगातार बढ़ोतरी हो रही है, लेकिन
WebViewsऔरActivitiesमें कोई बदलाव नहीं हो रहा है, तो लीक की समस्या, रिलीज़ नहीं किए गए नेटिव रिसॉर्स, डीओएम एलिमेंट या JavaScript इंजन बाइंडिंग की वजह से हो सकती है. ये आवंटन, नेटिव मेमोरी में मौजूद होते हैं और एआरटी गार्बेज कलेक्टर को बायपास करते हैं. इसलिए, ये स्टैंडर्ड Java लीक का पता लगाने वाले टूल को नहीं दिखते. साथ ही, ये तब तक इकट्ठा होते रहते हैं, जब तक ऑपरेटिंग सिस्टम ऐप्लिकेशन को बंद नहीं कर देता.
सीएलआई का इस्तेमाल करके, आइसोलेट की गई रेंडरर प्रोसेस की प्रोफ़ाइल बनाना
अपने ऐप्लिकेशन के पैकेज के नाम के साथ dumpsys meminfo चलाने पर, सिर्फ़ मुख्य होस्ट प्रोसेस के लिए मेमोरी का आउटपुट मिलता है. वेब पेजों को रेंडर करने वाली आइसोलेटेड रेंडरर प्रोसेस की जांच करने के लिए:
आइसोलेटेड रेंडरर सेवा का प्रोसेस आईडी (पीआईडी) ढूंढें:
adb shell dumpsys activity processes <var>PACKAGE_NAME</var> | grep "Isolated.*SandboxedProcessService"आउटपुट में, अलग की गई प्रोसेस का रिकॉर्ड और उसका पीआईडी RENDERER_PID दिखता है (उदाहरण के लिए,
22155):Isolated #5: ProcessRecord{... 22155:com.google.android.webview.debug:sandboxed_process0:...}रेंडरर प्रोसेस के मेमोरी ब्रेकडाउन की जांच करने के लिए, उसके PID का इस्तेमाल करें:
adb shell dumpsys meminfo <var>RENDERER_PID</var>ब्राउज़र-साइड फ़ुटप्रिंट का आकलन करने के लिए, होस्ट ऐप्लिकेशन प्रोसेस की जांच करें:
adb shell dumpsys meminfo <var>PACKAGE_NAME</var>
मेमोरी मैप और मेमोरी के बंटवारे की जांच करना
यह देखने के लिए कि कौनसे नेटिव सबसिस्टम या ऐलोकेटर, ऐनोनिमस मेमोरी का इस्तेमाल करते हैं, प्रोसेस मेमोरी मैप की जांच करें:
adb shell "cat /proc/$(pidof <var>PACKAGE_NAME</var>)/maps" | grep "anon:"यहां दी गई टेबल में, मेमोरी के इस्तेमाल से जुड़े सामान्य एनॉनिमस टैग और मेमोरी के इस्तेमाल में बढ़ोतरी से जुड़े उनके काम के बारे में बताया गया है:
| Memory Tag | सबसिस्टम | ऐप्लिकेशन और वेब कॉन्टेंट से मिलती-जुलती | मेमोरी बढ़ने की सामान्य वजह क्या है? |
|---|---|---|---|
[anon:partition_alloc] |
Chromium PartitionAlloc | WebView में डीओएम ट्री, रेंडरिंग बफ़र, V8 JavaScript हीप, और WebAssembly एक्ज़ीक्यूशन के लिए किए गए असाइनमेंट. |
हां (ज़्यादा): भारी वेब पेजों, मीडिया से भरपूर डीओएम को लोड करने या खारिज किए गए WebView इंस्टेंस पर सीधे तौर पर destroy() को कॉल न करने से, इस टैग की वैल्यू बढ़ जाती है. |
[anon:scudo...] या [anon:libc_malloc] |
Android नेटिव हीप ऐलोकेटर (Scudo / jemalloc) | एनडीके लाइब्रेरी, जेएनआई ब्रिज, और नेटिव ग्राफ़िक्स पाइपलाइन के ज़रिए इस्तेमाल किए जाने वाले सामान्य C/C++ नेटिव ऐलोकेशन. | हां (सामान्य से ज़्यादा): ऐसा तब होता है, जब नेटिव JNI रैपर या तीसरे पक्ष की C++ डिपेंडेंसी, नेविगेशन के दौरान रिलीज़ नहीं किए गए ऐलोकेशन को बनाए रखती हैं. |
[anon:...] (उदाहरण के लिए, [anon:quickjs_heap...]) |
कस्टम स्क्रिप्टिंग या नेटिव रनटाइम | एम्बेड किए गए JavaScript इंजन, कस्टम WebAssembly रनटाइम या कस्टम नेटिव बफ़र पूल. | हां (संदर्भ के हिसाब से): यह समस्या हाइब्रिड ऐप्लिकेशन में आम तौर पर होती है. ऐसा तब होता है, जब स्क्रिप्टिंग इंजन, नेटिव व्यू के साथ काम करते हैं और रनटाइम बाइंडिंग को क्लीन अप नहीं करते. |
ऐप्लिकेशन में मेमोरी के लिए इस्तेमाल होने वाले एपीआई की सीमाएं
ऐप्लिकेशन में मौजूद मेमोरी एपीआई (जैसे, Debug.getMemoryInfo या ActivityManager.getProcessMemoryInfo) सिर्फ़ कॉलिंग प्रोसेस को मेज़र करते हैं.
मल्टी-प्रोसेस मोड में, ये एपीआई आइसोलेटेड रेंडरर प्रोसेस की मेमोरी को कैप्चर नहीं कर सकते. कुल मेमोरी का सटीक आकलन करने के लिए, dumpsys meminfo, Perfetto या Android Studio Profiler जैसे सिस्टम टूल का इस्तेमाल करें.
हाइब्रिड ऐप्लिकेशन में ज़्यादा मेमोरी इस्तेमाल होने की समस्या को प्राथमिकता के आधार पर ठीक करना
बार-बार होने वाले WebView
इंटरैक्शन (जैसे कि वेब लिंक खोलना या वेब की मदद से काम करने वाले फ़ीड पर नेविगेट करना) के दौरान, मेमोरी के इस्तेमाल में अचानक हुई बढ़ोतरी की वजह का पता लगाने के लिए, यहां दिए गए ट्राइएज वर्कफ़्लो का इस्तेमाल करें. इससे यह पता लगाया जा सकेगा कि मेमोरी लीक, Java लेयर या नेटिव इंजन से हो रही है या नहीं:
लीक के टाइप (Java बनाम नेटिव) का पता लगाएं: उपयोगकर्ता के बार-बार ट्रांज़िशन करने से पहले और बाद में
dumpsys meminfo -a <var>PACKAGE_NAME</var> | grep -A 10 "Objects"चलाएं. जैसे, वेब लेख खोलना और बंद करना या फ़ीड में स्वाइप करना.- ध्यान दें: अगर
ActivitiesऔरWebViewsकी संख्या स्थिर रहती है (उदाहरण के लिए, 1–2 चालू इंस्टेंस), तो इसका मतलब है कि ऐप्लिकेशन मेंActivityकॉन्टेक्स्ट या JavaWebViewइंस्टेंस लीक नहीं हो रहे हैं.
- ध्यान दें: अगर
सभी इंटरैक्शन के लिए मेमोरी डेल्टा मेज़र करें (टाइम-सीरीज़ ट्रैकिंग): उपयोगकर्ता के कई इंटरैक्शन के लिए
dumpsys meminfoस्नैपशॉट कैप्चर करें, ताकि हर ट्रांज़िशन के लिए मेमोरी के इस्तेमाल की दर का हिसाब लगाया जा सके:- निरीक्षण: Java हीप मेमोरी का इस्तेमाल सीमित रहता है और यह सही तरीके से काम करती है. इस्तेमाल के दौरान यह बढ़ती है और गार्बेज कलेक्शन के बाद कम हो जाती है. हालांकि, निजी अन्य और नेटिव हीप मेमोरी का इस्तेमाल, हर ट्रांज़िशन के साथ कई मेगाबाइट तक बढ़ता जाता है. इससे यह साबित होता है कि लीक, एआरटी रनटाइम से बाहर की नेटिव मेमोरी में है.
स्टैंडर्ड Java हीप डंप (
.hprof) में कोई समस्या नहीं दिखेगी.
- निरीक्षण: Java हीप मेमोरी का इस्तेमाल सीमित रहता है और यह सही तरीके से काम करती है. इस्तेमाल के दौरान यह बढ़ती है और गार्बेज कलेक्शन के बाद कम हो जाती है. हालांकि, निजी अन्य और नेटिव हीप मेमोरी का इस्तेमाल, हर ट्रांज़िशन के साथ कई मेगाबाइट तक बढ़ता जाता है. इससे यह साबित होता है कि लीक, एआरटी रनटाइम से बाहर की नेटिव मेमोरी में है.
स्टैंडर्ड Java हीप डंप (
नाम रहित मेमोरी मैप की जांच करना: ADB का इस्तेमाल करके, प्रोसेस मेमोरी मैप की जांच करें. इसके लिए, मेमोरी मैप और मेमोरी के बंटवारे की जांच करना लेख पढ़ें:
adb shell "cat /proc/$(pidof <var>PACKAGE_NAME</var>)/maps" | grep "anon:"- निरीक्षण: मेमोरी का इस्तेमाल,
[anon:partition_alloc]या एम्बेड किए गए स्क्रिप्टिंग इंजन के हीप में ज़्यादा होता है. साथ ही, जेएनआई ग्लोबल रेफ़रंस में धीरे-धीरे बढ़ोतरी होती है. इससे पता चलता है कि Java व्यू को बदल दिया गया है, लेकिन पेज के मूल ऑब्जेक्ट या JavaScript बाइंडिंग को रिलीज़ नहीं किया गया है.
- निरीक्षण: मेमोरी का इस्तेमाल,
समस्या हल करना:
- पक्का करें कि रीसाइकल किए गए या हटाए गए हर
WebViewमें, चालू स्क्रिप्ट (stopLoading()) साफ़ तौर पर बंद हो जाती हैं, इतिहास मिट जाता है, औरdestroy()कॉल हो जाता है. - खारिज किए गए व्यू से जुड़े कस्टम JavaScript ब्रिज कॉलबैक या JNI ग्लोबल रेफ़रंस हटाएं.
- पुष्टि करें कि नेविगेशन ट्रांज़िशन के बाद,
Private Otherऔर प्रोसेस आरएसएस स्थिर हो जाते हैं.
- पक्का करें कि रीसाइकल किए गए या हटाए गए हर
अन्य संसाधन
मेमोरी और WebView परफ़ॉर्मेंस की गड़बड़ियों को ठीक करने और उनकी प्रोफ़ाइलिंग करने के बारे में ज़्यादा जानने के लिए, यहां दिए गए लेख पढ़ें:
- अपने ऐप्लिकेशन की मेमोरी मैनेज करना
- मेमोरी मैनेजमेंट के बारे में खास जानकारी
- वेब ऐप्लिकेशन डीबग करना