Android प्लैटफ़ॉर्म पर, सिस्टम ज़्यादा से ज़्यादा सिस्टम मेमोरी (रैम) का इस्तेमाल करने की कोशिश करता है. साथ ही, ज़रूरत पड़ने पर जगह खाली करने के लिए, मेमोरी को ऑप्टिमाइज़ करता है. इन ऑप्टिमाइज़ेशन से आपके गेम पर बुरा असर पड़ सकता है. ऐसा हो सकता है कि गेम धीमा हो जाए या पूरी तरह से बंद हो जाए. इन ऑप्टिमाइज़ेशन के बारे में ज़्यादा जानने के लिए, प्रोसेस के बीच मेमोरी का बंटवारा विषय पढ़ें.
डिवाइस के ठीक से काम करने के लिए, Android 17 (एपीआई लेवल 37) से सिस्टम, डिवाइस की कुल रैम के आधार पर ऐप्लिकेशन के लिए मेमोरी की सीमाएं लागू करना शुरू कर देता है. अगर कोई ऐप्लिकेशन इन सीमाओं से ज़्यादा मेमोरी का इस्तेमाल करता है, तो Android उस प्रोसेस को बंद कर देता है. साथ ही, उससे जुड़ा कोई स्टैक ट्रेस नहीं दिखाता है.
इस पेज पर, कम मेमोरी की वजह से गेम पर पड़ने वाले असर से बचने का तरीका बताया गया है.
onTrimMemory() को जवाब देना
सिस्टम, onTrimMemory() का इस्तेमाल करके आपके ऐप्लिकेशन को लाइफ़साइकल इवेंट की सूचना देता है. इससे आपके ऐप्लिकेशन को मेमोरी का इस्तेमाल कम करने का अच्छा मौका मिलता है. साथ ही, लो-मेमोरी किलर (एलएमके) से ऐप्लिकेशन को बंद होने से बचाया जा सकता है, ताकि अन्य ऐप्लिकेशन मेमोरी का इस्तेमाल कर सकें.
अगर आपका ऐप्लिकेशन बैकग्राउंड में बंद हो जाता है, तो अगली बार जब उपयोगकर्ता आपका ऐप्लिकेशन लॉन्च करेगा, तो उसे कोल्ड स्टार्ट होने में ज़्यादा समय लगेगा. बैकग्राउंड में जाने पर, जिन ऐप्लिकेशन का मेमोरी का इस्तेमाल कम हो जाता है उनके बैकग्राउंड में बंद होने की संभावना कम होती है.
मेमोरी कम करने के इवेंट का जवाब देते समय, यह सबसे अच्छा होता है कि आप उन बड़ी मेमोरी को रिलीज़ करें जिनकी तुरंत ज़रूरत नहीं है और जिन्हें ज़रूरत पड़ने पर फिर से बनाया जा सकता है. उदाहरण के लिए, अगर आपके ऐप्लिकेशन में बिटमैप की ऐसी कैश मेमोरी है जिसे स्थानीय तौर पर सेव की गई कंप्रेस की गई इमेज से डिकोड किया गया था, तो TRIM_MEMORY_UI_HIDDEN के जवाब में इस कैश मेमोरी को कम करना या हटाना अक्सर एक अच्छा विचार होता है.
Kotlin
class MainActivity : AppCompatActivity(), ComponentCallbacks2 { override fun onTrimMemory(level: Int) { if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Release memory related to UI elements, such as bitmap caches. } if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { // Release memory related to background processing, such as by // closing a database connection. } } }
Java
public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 { public void onTrimMemory(int level) { switch (level) { if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Release memory related to UI elements, such as bitmap caches. } if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { // Release memory related to background processing, such as by // closing a database connection. } } } }
मेमोरी बजट को लेकर ज़्यादा सतर्क रहें
मेमोरी खत्म होने से बचाने के लिए, बजट मेमोरी को कम से कम रखें. इन बातों का ध्यान रखें:
- फ़िज़िकल रैम का साइज़: गेम अक्सर डिवाइस पर मौजूद फ़िज़िकल रैम का ¼ से ½ हिस्सा इस्तेमाल करते हैं.
- ज़ेडरैम का ज़्यादा से ज़्यादा साइज़: ज़ेडरैम का साइज़ ज़्यादा होने का मतलब है कि गेम के पास मेमोरी को असाइन करने के लिए ज़्यादा जगह है. यह साइज़, डिवाइस के हिसाब से अलग-अलग हो सकता है. इस वैल्यू को ढूंढने के लिए,
/proc/meminfoमेंSwapTotalदेखें. - ओएस के लिए मेमोरी का इस्तेमाल: जिन डिवाइसों में सिस्टम प्रोसेस के लिए ज़्यादा रैम तय की जाती है उनमें आपके गेम के लिए कम मेमोरी बचती है. सिस्टम की प्रोसेस बंद करने से पहले, सिस्टम आपके गेम की प्रोसेस बंद कर देता है.
- इंस्टॉल किए गए ऐप्लिकेशन के लिए मेमोरी का इस्तेमाल: अपने गेम को उन डिवाइसों पर टेस्ट करें जिन पर कई ऐप्लिकेशन इंस्टॉल हैं. सोशल मीडिया और चैट ऐप्लिकेशन लगातार चलते रहते हैं. इससे डिवाइस में उपलब्ध स्टोरेज पर असर पड़ता है.
अगर आपको मेमोरी के लिए तय किए गए बजट का पालन करने में परेशानी हो रही है, तो मेमोरी के इस्तेमाल के लिए ज़्यादा लचीला तरीका अपनाएं. अगर सिस्टम में मेमोरी कम होने की वजह से समस्याएं आ रही हैं, तो गेम के लिए इस्तेमाल की जा रही मेमोरी की मात्रा कम करें. उदाहरण के लिए, onTrimMemory() के जवाब में कम रिज़ॉल्यूशन वाले टेक्सचर असाइन करें या कम शेडर सेव करें. मेमोरी असाइन करने के इस डाइनैमिक तरीके के लिए, डेवलपर को ज़्यादा काम करना पड़ता है. खास तौर पर, गेम डिज़ाइन के चरण में.
थ्रैशिंग से बचना
थ्रैशिंग तब होती है, जब मेमोरी कम होती है, लेकिन इतनी कम नहीं होती कि गेम बंद हो जाए.
इस स्थिति में, kswapd ने उन पेजों को वापस ले लिया है जिनकी गेम को अब भी ज़रूरत है. इसलिए, यह मेमोरी से पेजों को फिर से लोड करने की कोशिश करता है. मेमोरी में जगह कम होने की वजह से, पेजों को लगातार स्वैप किया जा रहा है.
सिस्टम ट्रेसिंग इस स्थिति को थ्रेड के तौर पर रिपोर्ट करती है. इसमें kswapd लगातार चलता रहता है.
थ्रैशिंग का एक लक्षण यह है कि फ़्रेम को रेंडर होने में ज़्यादा समय लगता है. ऐसा हो सकता है कि फ़्रेम को रेंडर होने में एक सेकंड या इससे ज़्यादा समय लगे. इस समस्या को हल करने के लिए, गेम की मेमोरी फ़ुटप्रिंट को कम करें.
उपलब्ध टूल इस्तेमाल करना
Android में कई टूल उपलब्ध हैं. इनसे यह समझने में मदद मिलती है कि सिस्टम मेमोरी को कैसे मैनेज करता है.
Meminfo
यह टूल, मेमोरी के आंकड़े इकट्ठा करता है. इससे यह पता चलता है कि पीएसएस मेमोरी कितनी असाइन की गई थी और इसका इस्तेमाल किन कैटगरी के लिए किया गया था.
meminfo के आंकड़ों को इनमें से किसी एक तरीके से प्रिंट करें:
adb shell dumpsys meminfo package-nameकमांड का इस्तेमाल करें.- Android Debug API से
MemoryInfoकॉल का इस्तेमाल करें.
PrivateDirty आंकड़े से, प्रोसेस में मौजूद ऐसी रैम की जानकारी मिलती है जिसे डिस्क पर पेज नहीं किया जा सकता. साथ ही, इसे किसी अन्य प्रोसेस के साथ शेयर नहीं किया जाता. जब प्रोसेस बंद हो जाती है, तब इस मेमोरी का ज़्यादातर हिस्सा सिस्टम के लिए उपलब्ध हो जाता है.
मेमोरी ट्रेसपॉइंट
मेमोरी ट्रेसपॉइंट, आपके गेम में इस्तेमाल हो रही आरएसएस मेमोरी की मात्रा को ट्रैक करते हैं. आरएसएस मेमोरी के इस्तेमाल का हिसाब लगाना, पीएसएस के इस्तेमाल का हिसाब लगाने से ज़्यादा तेज़ होता है. आरएसएस का हिसाब तेज़ी से लगाया जा सकता है. इसलिए, आरएसएस से मेमोरी के साइज़ में होने वाले बदलावों के बारे में ज़्यादा सटीक जानकारी मिलती है. इससे मेमोरी के ज़्यादा इस्तेमाल का ज़्यादा सटीक मेज़रमेंट किया जा सकता है. इसलिए, उन पीक को नोटिस करना आसान होता है जिनकी वजह से गेम में मेमोरी खत्म हो सकती है.
Perfetto और लंबे ट्रेस
Perfetto, डिवाइस पर परफ़ॉर्मेंस और मेमोरी की जानकारी इकट्ठा करने और उसे वेब-आधारित यूज़र इंटरफ़ेस (यूआई) में दिखाने के लिए टूल का एक सुइट है. यह ट्रेस को लंबे समय तक सेव करता है, ताकि यह देखा जा सके कि समय के साथ आरएसएस में कैसे बदलाव होता है. इसके अलावा, ऑफ़लाइन प्रोसेसिंग के लिए, इससे मिले डेटा पर SQL क्वेरी भी जारी की जा सकती हैं. सिस्टम ट्रेसिंग ऐप्लिकेशन से लंबे ट्रेस चालू करें. पक्का करें कि ट्रेस के लिए, memory:Memory कैटगरी चालू हो. डेवलपमेंट और टेस्टिंग के दौरान कस्टम मेमोरी इंस्ट्रूमेंटेशन के लिए, (बीटा) heapprofd API का भी इस्तेमाल किया जा सकता है.
heapprofd
heapprofd, मेमोरी को ट्रैक करने वाला एक टूल है. यह Perfetto का हिस्सा है. यह टूल, मेमोरी लीक का पता लगाने में आपकी मदद कर सकता है. इसके लिए, यह दिखाता है कि malloc का इस्तेमाल करके मेमोरी कहां असाइन की गई थी. heapprofd को Python स्क्रिप्ट का इस्तेमाल करके शुरू किया जा सकता है. साथ ही, इस टूल का ओवरहेड कम होता है. इसलिए, यह Malloc Debug जैसे अन्य टूल की तरह परफ़ॉर्मेंस पर असर नहीं डालता.
गड़बड़ी की रिपोर्ट
bugreport एक लॉगिंग टूल है. इससे यह पता लगाया जा सकता है कि मेमोरी खत्म होने की वजह से आपका गेम क्रैश हुआ है या नहीं. इस टूल का आउटपुट, logcat के मुकाबले ज़्यादा जानकारी देता है. यह मेमोरी डीबग करने के लिए काम का टूल है. इससे यह पता चलता है कि मेमोरी खत्म होने की वजह से आपका गेम क्रैश हुआ है या LMK ने उसे बंद कर दिया है.
ज़्यादा जानकारी के लिए, बग रिपोर्ट कैप्चर करना और उन्हें पढ़ना लेख पढ़ें.