Android पर गेमिंग के बेहतर और शानदार अनुभव देने के लिए, मेमोरी ऑप्टिमाइज़ेशन ज़रूरी है. इस गाइड में बताया गया है कि मेमोरी का बेहतर इस्तेमाल क्यों ज़रूरी है और Android ऑपरेटिंग सिस्टम, प्रोसेस मेमोरी की सीमाओं को कैसे मैनेज करता है. साथ ही, Google Play Console में मेमोरी की नई मेट्रिक के बारे में बताया गया है. इनकी मदद से, अपने गेम की तकनीकी क्वालिटी को मॉनिटर किया जा सकता है और उसे बेहतर बनाया जा सकता है.
मेमोरी ऑप्टिमाइज़ेशन की अहमियत
गेम की मेमोरी को ऑप्टिमाइज़ करना ज़रूरी है, ताकि खिलाड़ी आपके गेम से जुड़े रहें, गेम ज़्यादा डिवाइसों के साथ काम कर सके, और प्लैटफ़ॉर्म के क्वालिटी स्टैंडर्ड का पालन किया जा सके:
- कोल्ड स्टार्ट से बचाव (उपयोगकर्ता अनुभव और उपयोगकर्ता को बनाए रखना): जब कोई खिलाड़ी कुछ समय के लिए आपके गेम से स्विच करता है (उदाहरण के लिए, किसी सूचना का जवाब देने या मैसेज देखने के लिए), तो ऑपरेटिंग सिस्टम गेम की प्रोसेस को बैकग्राउंड में डाल देता है. अगर बैकग्राउंड में गेम का मेमोरी फ़ुटप्रिंट बहुत ज़्यादा है, तो सिस्टम का लो मेमोरी किलर (एलएमके), गेम की प्रोसेस को बंद करने को प्राथमिकता देता है. इससे फ़ोरग्राउंड टास्क के लिए रैम खाली हो जाती है. जब उपयोगकर्ता अगली बार गेम को फिर से शुरू करता है, तो गेम को तुरंत और आसानी से शुरू करने के बजाय, उसे कोल्ड स्टार्ट करना पड़ता है. इसमें स्टोरेज से भारी ग्राफ़िक ऐसेट, ऑडियो, और गेम इंजन बाइनरी को पूरी तरह से फिर से लोड करना पड़ता है. बैकग्राउंड में मेमोरी का कम इस्तेमाल करने से, बैकग्राउंड में चल रहे ऐप्लिकेशन को बिना सूचना के बंद होने से रोका जा सकता है. इससे उपयोगकर्ता की स्थिति को सुरक्षित रखा जा सकता है. साथ ही, यह पक्का किया जा सकता है कि खिलाड़ी तुरंत अपना सेशन फिर से शुरू कर सकें. सिस्टम एलएमके के काम करने के तरीके के बारे में ज़्यादा जानने के लिए, Android की ज़रूरी जानकारी - लो मेमोरी किलर गाइड देखें.
- इकोसिस्टम और डिवाइस की परफ़ॉर्मेंस: मेमोरी का सही तरीके से इस्तेमाल न होने और मेमोरी लीक होने से, सिस्टम की परफ़ॉर्मेंस खराब हो जाती है. जब सिस्टम मेमोरी कम होती है, तो सिस्टम पर काफ़ी दबाव पड़ता है. इससे फ़्रेम रेट कम हो जाता है, यूज़र इंटरफ़ेस (यूआई) रुक-रुककर काम करता है, और ऑडियो में गड़बड़ियां होती हैं. अगर मेमोरी पर बहुत ज़्यादा दबाव पड़ता है, तो सिस्टम का लो मेमोरी किलर (एलएमके), बैकग्राउंड में चल रही प्रोसेस को तुरंत बंद कर देता है. इससे अन्य ऐप्लिकेशन को कोल्ड स्टार्ट होने में ज़्यादा समय लगता है. साथ ही, जब खिलाड़ी एक टास्क से दूसरे टास्क पर स्विच करते हैं, तो उपयोगकर्ता की स्थिति का डेटा मिट जाता है.
- प्लैटफ़ॉर्म-लेवल पर प्रोसेस बंद करना: Android 17 (एपीआई लेवल 37) से, सिस्टम ज़्यादा मेमोरी इस्तेमाल करने वाली प्रोसेस को बंद करने के लिए ज़्यादा सक्रिय है. अगर आपके गेम का फ़ुटप्रिंट बहुत ज़्यादा है, तो ओएस स्टैंडर्ड स्टैक ट्रेस जनरेट किए बिना, गेम की प्रोसेस को अचानक बंद कर सकता है.
- डिवाइस के साथ काम करना: फ़्लैगशिप डिवाइसों में 12 जीबी से 16 जीबी रैम होती है. हालांकि, दुनिया भर में गेम खेलने वाले ज़्यादातर लोग, 4 जीबी या 6 जीबी रैम वाले डिवाइसों का इस्तेमाल करते हैं. मेमोरी को सही तरीके से मैनेज करने से, यह पक्का होता है कि आपका गेम सभी हार्डवेयर टियर पर ऐक्सेस किया जा सके और रिस्पॉन्सिव बना रहे. इसके लिए, आपको अलग-अलग और जटिल ऐसेट पैकेज की ज़रूरत नहीं पड़ती.
Android में मेमोरी के बारे में जानकारी
मेमोरी-बजट की असरदार रणनीतियां बनाने के लिए, डेवलपर को यह समझना होगा कि Android प्लैटफ़ॉर्म, फ़िज़िकल मेमोरी को कैसे मैनेज करता है और आपके गेम के ऐक्टिव फ़ुटप्रिंट को कैसे मेज़र करता है.
Android मेमोरी से जुड़े मुख्य सिद्धांत
प्लैटफ़ॉर्म-लेवल पर मेमोरी मैनेज करने से जुड़े बुनियादी सिद्धांतों के बारे में जानने के लिए, आधिकारिक मेमोरी मैनेज करने के बारे में खास जानकारी दस्तावेज़ देखें. इस संसाधन में आर्किटेक्चर के चार विषयों के बारे में बताया गया है:
- मेमोरी की खास जानकारी: Android, रैम को मैनेज करने के लिए पेजिंग और मेमोरी-मैपिंग (mmap) का इस्तेमाल करता है. यह डिस्क पर मौजूद पारंपरिक स्वैप फ़ाइल के साथ काम नहीं करता. इसके बजाय, यह फ़िज़िकल मेमोरी को खाली करने के लिए, पेज कंप्रेशन (zRAM का इस्तेमाल करके) और पेज रिक्लेमेशन पर निर्भर करता है.
- प्रोसेस के बीच मेमोरी का बंटवारा: Android, पूरे सिस्टम में रैम शेयर करता है. यह Dalvik या ART वर्चुअल मशीन के एक्ज़ीक्यूशन के लिए खास हीप असाइन करता है. साथ ही, नेटिव डेवलपमेंट एनवायरमेंट (जैसे, C++ गेम इंजन) को नेटिव सिस्टम हीप से मेमोरी का अनुरोध करने की अनुमति देता है.
- ऐप्लिकेशन की मेमोरी मैनेज करना: Android, मल्टी-प्रोसेस मॉडल के तहत काम करता है. इसलिए, यह उम्मीद की जाती है कि ऐप्लिकेशन, अपनी लाइफ़साइकल की स्थिति को डाइनैमिक तौर पर मॉनिटर करें. साथ ही, सिस्टम की परफ़ॉर्मेंस को बेहतर बनाने के लिए, वे अपनी मर्ज़ी से ऐसे संसाधनों को रिलीज़ करें जिनकी ज़रूरत नहीं है. जैसे, कैश मेमोरी में सेव नहीं किए गए ग्राफ़िक और बिट मैप.
- प्रोसेस और थ्रेड की खास जानकारी: सिस्टम, प्रोसेस को उनकी मौजूदा विज़िबिलिटी और अहमियत के आधार पर हैरारकी में बांटता है. इससे यह तय होता है कि मेमोरी कम होने पर, कौनसी प्रोसेस चालू रखी जाएं और कौनसी प्रोसेस सबसे पहले बंद की जाएं.
कुल मेमोरी फ़ुटप्रिंट की मेट्रिक
Android 17 में प्लैटफ़ॉर्म-लेवल पर उपलब्ध मेमोरी लिमिटर, प्रोसेस के दौरान इस्तेमाल की गई मेमोरी का आकलन करता है. इसके लिए, वह कुल रेज़िडेंट साइज़ (आरएसएस) या वर्चुअल मेमोरी के साइज़ के बजाय, कुल मेमोरी फ़ुटप्रिंट का इस्तेमाल करता है.
किसी प्रोग्राम के चलने के दौरान, इस्तेमाल की जाने वाली कुल मेमोरी (मेमोरी फ़ुटप्रिंट) = बिना सोर्स फ़ाइल वाली आरएसएस मेमोरी (RssAnon) + अनकंप्रेस्ड स्वैप मेमोरी (VmSwap)
गेम को प्लैटफ़ॉर्म की सीमाओं से ज़्यादा मेमोरी इस्तेमाल करने से रोकने के लिए, आपको यह समझना होगा कि सिस्टम लेवल पर ये मेट्रिक क्या दिखाती हैं. इन मेट्रिक, फ़िज़िकल रैम के ऐलोकेशन, और फ़ाइल-बैक्ड पेजों को मैनेज करने के तरीके के बारे में ज़्यादा जानने के लिए, मेमोरी के इस्तेमाल को मॉनिटर करें गाइड में आरएसएस और स्वैप मेट्रिक को समझना लेख पढ़ें.
मेमोरी से जुड़ी पाबंदियां
सिस्टम की परफ़ॉर्मेंस को बेहतर बनाए रखने और यह पक्का करने के लिए कि ऐप्लिकेशन ज़्यादा संसाधनों का इस्तेमाल न करें, Android प्लैटफ़ॉर्म, चल रही प्रोसेस के लिए मेमोरी की सीमाओं को मैनेज करता है.
Android 17 और इसके बाद के वर्शन में मेमोरी लिमिटर
Android 17 (एपीआई लेवल 37) और इसके बाद के वर्शन, हर ऐप्लिकेशन के लिए मेमोरी की तय सीमा को सख्ती से मैनेज करते हैं. इसके लिए, Linux cgroup v2 का इस्तेमाल किया जाता है, ताकि कोई ऐप्लिकेशन पूरे सिस्टम को क्रैश न कर सके. तकनीकी तौर पर इसे लागू करने के बारे में ज़्यादा जानने के लिए, एओएसपी मेमोरी लिमिटर गाइड और मेमोरी की परफ़ॉर्मेंस को प्राथमिकता देना: Android 17 के लिए ज़रूरी कदम ब्लॉग देखें.
- यह कैसे काम करता है: मेमोरी लिमिटर, ऐप्लिकेशन की सभी प्रोसेस पर नज़र रखता है. साथ ही, प्रोसेस की लाइफ़साइकल की स्थिति के आधार पर, डाइनैमिक तौर पर सीमाएं तय करता है:
- दिखने वाली प्रोसेस (फ़ोरग्राउंड): ऐप्लिकेशन की ऐसी प्रोसेस जो फ़िलहाल यूज़र इंटरफ़ेस (यूआई) दिखा रही हैं. इनसे उम्मीद की जाती है कि वे ज़्यादा रिसॉर्स वाले वर्किंग सेट को चलाएं. साथ ही, इन्हें ज़्यादा उदार सीमा दी जाती है.
- न दिखने वाली प्रोसेस (बैकग्राउंड या सेवाएं): यूज़र इंटरफ़ेस (यूआई) दिखाए बिना ऐक्टिव रहने वाली ऐप्लिकेशन प्रोसेस के लिए, ज़्यादा पाबंदियों वाला बजट तय किया जाता है.
- कर्नल एट्रिब्यूट: यह सेवा दो मुख्य एट्रिब्यूट पर निर्भर करती है:
memory.high: सॉफ़्ट लिमिट. इस सीमा के पार होने पर, कर्नल प्रोसेस को धीमा कर देता है और मेमोरी को तेज़ी से वापस पाने की कोशिश करता है. इस वजह से, गेम की परफ़ॉर्मेंस में गिरावट आ सकती है.memory.swap.max: यह प्रोसेस के लिए इस्तेमाल किए जा सकने वाले स्वैप या zRAM स्पेस पर हार्ड कैप को मैनेज करता है.
- प्रोसेस बंद होने का तरीका: अगर कोई प्रोसेस
memory.highसे ज़्यादा एनॉनिमस मेमोरी का इस्तेमाल करती है और स्वैप स्पेस खत्म हो जाता है, तो मेमोरी का ऐलोकेशन नहीं हो पाता है. साथ ही, ओएस उस प्रोसेस को बिना किसी सूचना के बंद कर देता है. इस तरह से बंद किए गए ऐप्लिकेशन कोApplicationExitInfoका इस्तेमाल करके लॉग किया जाता है. इसके लिए, बंद होने की वजह के तौर पर मेमोरी लिमिटर को चुना जाता है. यह सुविधा, Android 17 (26Q4) से उपलब्ध है.
Play Console की ज़रूरी जानकारी में, मेमोरी की नई सीमाएं
डेवलपर को मेमोरी से जुड़ी समस्याओं का पहले से पता लगाने में मदद करने के लिए, Google Play, Play Console में 'Android की ज़रूरी जानकारी' सेक्शन में नई मेट्रिक जोड़ रहा है. Play Console, आपके गेम सेशन के 90वें पर्सेंटाइल (P90) की बिना सोर्स फ़ाइल वाली आरएसएस मेमोरी और स्वैप मेमोरी फ़ुटप्रिंट को ट्रैक करता है. इससे, आउटलायर की पहचान करने में मदद मिलती है.
चेतावनी और नीति उल्लंघन ठीक करने के तरीके के थ्रेशोल्ड को, डिवाइस की फ़िज़िकल रैम क्षमता और प्रोसेस की स्थितियों के आधार पर तय किया जाता है. ये सीमाएं दो अलग-अलग चरणों में लागू होती हैं.
ज़्यादा जानकारी वाले दिशा-निर्देशों और मेमोरी की सीमाओं के बारे में जानने के लिए, Android की ज़रूरी जानकारी - 'ऐप्लिकेशन की खराब परफ़ॉर्मेंस के थ्रेशोल्ड क्या हैं? लेख पढ़ें.
उपयोगकर्ता को दिखने वाली सेवाएं
Perceptible Services, बैकग्राउंड में चलने वाली ऐसी ज़रूरी प्रोसेस होती हैं जिनके बारे में Android सिस्टम को लगता है कि उपयोगकर्ता को इनकी जानकारी होनी चाहिए. इस स्थिति में, चल रही सभी प्रोसेस शामिल होती हैं:
- फ़ोरग्राउंड सेवाएं (एफ़जीएस)
- हाई-प्रायाॅरिटी वाले टास्क
- उपयोगकर्ता की ओर से किए जाने वाले डेटा ट्रांसफ़र के टास्क
- सिस्टम से जुड़ी सेवाएं या अन्य ऐप्लिकेशन से जुड़ी सेवाएं
Perceptible Services को बैकग्राउंड में लंबे समय तक चलने वाले ज़रूरी टास्क के लिए डिज़ाइन किया गया है. इसलिए, इनमें लाइफ़साइकल लीक होने की संभावना ज़्यादा होती है. Android प्लैटफ़ॉर्म की मेमोरी की सीमाएं, इस स्थिति को फ़ोरग्राउंड नहीं मानती हैं. इसका मतलब है कि अगर आपका गेम बैकग्राउंड में चल रहा है, लेकिन वह किसी ऐसी सेवा को चलाता रहता है जो उपयोगकर्ता को दिखती है, तो उस पर बैकग्राउंड या सेवा की मेमोरी की ज़्यादा सख्त सीमाएं लागू होती हैं. इनके बारे में Play के सहायता केंद्र पेज पर बताया गया है. गेम को फ़ोरग्राउंड से बैकग्राउंड में दिखने वाली सेवा की स्थिति में जाने पर, ग़ैर-ज़रूरी ऐसेट को तुरंत हटा देना चाहिए.
R8 से जुड़ी ज़रूरी शर्तें
बाइट कोड के साइज़ को कम करने और Java प्रोसेस के बुनियादी ओवरहेड को कम करने के लिए, Google Play Console, कोड ऑप्टिमाइज़ेशन का आकलन करता है. यह ऐप्लिकेशन की क्वालिटी से जुड़े दिशा-निर्देशों का हिस्सा है. गेम के लिए, ऑप्टिमाइज़ेशन से जुड़ी ज़रूरी शर्तों और सीमाओं के बारे में ज़्यादा जानने के लिए, Android की ज़रूरी जानकारी वाले दस्तावेज़ में DEX कोड ऑप्टिमाइज़ेशन देखें.
किसी स्टैंडर्ड Android प्रोजेक्ट में R8 को कॉन्फ़िगर करने के लिए, ऐप्लिकेशन ऑप्टिमाइज़ेशन चालू करें गाइड में दिया गया तरीका अपनाएं. ऐडवांस श्रिंकिंग और ऑप्टिमाइज़ेशन सेटिंग चालू करने के लिए, R8 को फ़ुल मोड में इस्तेमाल करें देखें. यह पता लगाने के लिए कि कौनसे नियम R8 को क्लास को छिपाने या इस्तेमाल न किए जा रहे कोड को हटाने से रोक रहे हैं, R8 Configuration Analyzer का इस्तेमाल करें.
अगर गेम इंजन का इस्तेमाल करके गेम बनाया जा रहा है, तो R8 का डिफ़ॉल्ट व्यवहार, इंजन और उसके वर्शन के हिसाब से अलग-अलग होता है:
- Unity: कोड की काट-छांट करने की सुविधा डिफ़ॉल्ट रूप से बंद होती है. इसलिए, आपको इसे अपनी प्रोजेक्ट सेटिंग में जाकर चालू करना होगा. वर्शन के लिए सहायता और कॉन्फ़िगरेशन के चरणों के बारे में ज़्यादा जानकारी के लिए, R8 की मदद से Unity कोड को छोटा और ऑप्टिमाइज़ करना लेख पढ़ें.
- Unreal Engine: UE 4.25 और इसके बाद के वर्शन में, रिलीज़ के लिए तैयार बिल्ड में R8 डिफ़ॉल्ट रूप से चालू होता है. इसके लिए, आपको जेएनआई ब्रिज और प्लगिन के लिए, कीप रूल मैनेज करने होंगे. वर्शन की जानकारी और यूपीएल कॉन्फ़िगरेशन के बारे में ज़्यादा जानने के लिए, R8 की मदद से Unreal Engine कोड को छोटा और ऑप्टिमाइज़ करना लेख पढ़ें.
बिट मैप के लिए ज़रूरी शर्तें
बिट मैप, आधुनिक हाई-फ़िडेलिटी गेम में मेमोरी के इस्तेमाल का एक बड़ा हिस्सा होते हैं. बिटमैप पिक्सल डेटा, Android 8.0 (एपीआई लेवल 26) और इसके बाद के वर्शन पर, सीधे तौर पर अनमैनेज्ड नेटिव हीप में सेव किया जाता है. इसलिए, इमेज को ऑप्टिमाइज़ किए बिना लोड करने से, प्रोसेस प्लैटफ़ॉर्म की मेमोरी थ्रेशोल्ड को पार कर सकती हैं. इमेज को स्केल करने और कैश मेमोरी में सेव करने के सबसे सही तरीकों के बारे में जानने के लिए, इमेज के इस्तेमाल को ऑप्टिमाइज़ करना लेख पढ़ें.
मेमोरी के इस्तेमाल पर नज़र रखना
अपने गेम की मेमोरी को असरदार तरीके से ऑप्टिमाइज़ करने के लिए, आपको सबसे पहले यह समझना होगा कि Android प्लैटफ़ॉर्म, मेमोरी के फ़ुटप्रिंट को कैसे मेज़र करता है. Android 17 में, मेमोरी मेट्रिक को अपडेट किया गया है. इससे, बिना सोर्स फ़ाइल वाली आरएसएस मेमोरी (RssAnon) और कंप्रेस नहीं की गई स्वैप मेमोरी (VmSwap) के योग को ट्रैक किया जा सकता है. इसमें, फ़ाइल-बैक्ड या जीपीयू-प्राइवेट मेमोरी शामिल नहीं है. इस गाइड में Perfetto और meminfo जैसे सिस्टम-लेवल टूल इस्तेमाल करने, ProfilingManager और onTrimMemory जैसे डाइग्नोस्टिक एपीआई लागू करने, और Unity और Unreal Engine में सटीक मेमोरी का बंटवारा निकालने का तरीका बताया गया है. अपने गेम की प्रोफ़ाइल को सटीक तरीके से बनाने का तरीका जानें. साथ ही, रनटाइम मेमोरी पोलिंग की वजह से होने वाली परफ़ॉर्मेंस की समस्याओं से बचने का तरीका जानें.
ज़्यादा जानकारी के लिए, मेमोरी के इस्तेमाल पर नज़र रखना लेख पढ़ें.
मेमोरी का इस्तेमाल कम करने की रणनीतियां
गेम इंजन, क्रॉस-प्लैटफ़ॉर्म डेवलपमेंट को आसान बनाते हैं. हालांकि, डिफ़ॉल्ट रूप से मेमोरी को मैनेज करने की उनकी सुविधा, ओएस-लेवल पर मेमोरी की सीमाओं को ट्रिगर कर सकती है. इस पेज पर, Unity और Unreal Engine के लिए खास तौर पर तैयार किए गए ऑप्टिमाइज़ेशन के व्यावहारिक चरणों के बारे में बताया गया है. जानें कि Java पर आधारित onTrimMemory पर भरोसा करने से, Unity में डेडलॉक क्यों हो सकते हैं. साथ ही, नेटिव लाइफ़साइकल कॉलबैक इस्तेमाल करने का तरीका जानें. आपको ऐसेट-लेवल पर ऑप्टिमाइज़ेशन करने के मुख्य तरीके भी पता चलेंगे. जैसे, एएसटीसी 8x8 टेक्सचर कंप्रेशन का इस्तेमाल करना और ऐसेट अनलोड को कॉन्फ़िगर करना. इससे आपका गेम सभी हार्डवेयर टियर पर आसानी से चलता रहेगा.
ज़्यादा जानकारी के लिए, मेमोरी का इस्तेमाल कम करना लेख पढ़ें.