Android सिस्टम में, Memory Limiter (Android 17+) के लिए मेमोरी की सीमा का थ्रेशोल्ड और Google Play Console में मेमोरी की ज़रूरी जानकारी के लिए बेंचमार्क वैल्यू, 'anonymous RSS + swap' है. यह वैल्यू, प्रोसेस के लिए इस्तेमाल की गई फ़िज़िकल मेमोरी के लेवल को दिखाती है. यह एक अहम मेट्रिक है. ऐप्लिकेशन के सही तरीके से काम करने के लिए, इस पर नज़र रखना ज़रूरी है.
फ़िलहाल, रनटाइम या Unity Engine में स्टैटिक तौर पर, 'anonymous RSS + swap' से मेल खाने वाले मेमोरी का इस्तेमाल का सटीक आकलन करना मुश्किल है.
इस समस्या को हल करने के लिए, इस पेज पर यह बताया गया है कि Unity Engine के एनवायरमेंट में, Unity Profiler, ProfileRecorder API, और Unity Memory Profiler का इस्तेमाल करके, 'anonymous RSS + swap' वैल्यू को ज़्यादा भरोसेमंद तरीके से कैसे ट्रैक किया जा सकता है.
रनटाइम के दौरान मेमोरी के इस्तेमाल की जानकारी देखना
Unity में, रनटाइम के दौरान Android की 'बिना सोर्स फ़ाइल वाली आरएसएस + स्वैप' मेमोरी के सटीक इस्तेमाल का पता लगाना मुश्किल हो सकता है. हालांकि, Unity के बिल्ट-इन Profiler API का इस्तेमाल करके, इस वैल्यू का अनुमान लगाया जा सकता है. इसमें ~10% का अंतर हो सकता है.
पहला तरीका: प्रोफ़ाइलर का इस्तेमाल करना
मेमोरी के कुल इस्तेमाल का अनुमान लगाने के लिए, यहां दिए गए Profiler API से मिली वैल्यू को जोड़ा जा सकता है:
using UnityEngine;
using UnityEngine.Profiling;
public class MemoryMonitor : MonoBehaviour
{
public long GetEstimatedMemoryUsageBytes()
{
long totalReserved = Profiler.GetTotalReservedMemoryLong();
long monoHeapSize = Profiler.GetMonoHeapSizeLong();
return totalReserved + monoHeapSize;
}
}
दूसरा तरीका: ProfilerRecorder क्लास का इस्तेमाल करना
ProfilerRecorder का इस्तेमाल करके, कुल रिज़र्व की गई मेमोरी और Gfx के लिए रिज़र्व की गई मेमोरी मेट्रिक को ट्रैक किया जा सकता है:
डेवलपमेंट बिल्ड में: 'कुल रिज़र्व की गई मेमोरी' - 'Gfx के लिए रिज़र्व की गई मेमोरी' का हिसाब लगाएं.
रिलीज़ बिल्ड में: सीधे तौर पर 'कुल रिज़र्व की गई मेमोरी' का इस्तेमाल करें.
using Unity.Profiling;
using UnityEngine;
public class MemoryMonitor : MonoBehaviour
{
ProfilerRecorder totalRecorder;
#if DEVELOPMENT_BUILD
ProfilerRecorder gfxRecorder;
#endif
private void OnEnable()
{
totalRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Total Reserved Memory");
#if DEVELOPMENT_BUILD
gfxRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Gfx Reserved Memory");
#endif
}
private void OnDisable()
{
totalRecorder.Dispose();
#if DEVELOPMENT_BUILD
gfxRecorder.Dispose();
#endif
}
public long GetEstimatedMemoryUsageBytes()
{
#if DEVELOPMENT_BUILD
if (totalRecorder.Valid && gfxRecorder.Valid)
{
return totalRecorder.LastValue - gfxRecorder.LastValue;
}
#else
if (totalRecorder.Valid)
{
return totalRecorder.LastValue;
}
#endif
return 0;
}
}
सीमाएं:
मेमोरी के ऐसे असाइनमेंट जिन्हें Unity के Memory Manager से नहीं किया जाता (जैसे, NativeMalloc(IntPtr size)), उन्हें इन एपीआई से ट्रैक नहीं किया जा सकता.
ऐसा हो सकता है कि ये एपीआई, Unity के आपके वर्शन के साथ काम न करें.
मेमोरी ब्रेकडाउन का विश्लेषण करना (स्टैटिक विश्लेषण)
अगर रनटाइम के दौरान ज़्यादा मेमोरी इस्तेमाल होने का पता चलता है, तो आपको यह पता लगाना होगा कि मेमोरी कहां इस्तेमाल हो रही है. मेमोरी डिस्ट्रिब्यूशन का विश्लेषण करने से, गैर-ज़रूरी मेमोरी को हटाने और गेम के कुल मेमोरी फ़ुटप्रिंट को कम करने में मदद मिलती है.
Unity Memory Profiler
मेमोरी का बेहतर तरीके से विश्लेषण करने और अपने गेम को ऑप्टिमाइज़ करने के लिए, Unity Memory Profiler पैकेज का इस्तेमाल करें. Android OS के 'बिना सोर्स फ़ाइल वाली आरएसएस मेमोरी और स्वैप मेमोरी' के इस्तेमाल से जुड़े आइटम ढूंढने के लिए:
- Unity Memory Profiler का इस्तेमाल करके स्नैपशॉट कैप्चर करें.
- स्नैपशॉट खोलें और डिवाइस में मौजूद मेमोरी > डिवाइस में मौजूद मेमोरी पर जाएं.
इन आइटम का योग निकालो:
- ट्रैक नहीं किया गया
- Android रनटाइम
- नेटिव
- मैनेज किया गया
पहली इमेज. मेमोरी के ब्यौरे, रेज़िडेंट मेमोरी में सेव किए जाते हैं
कुल योग, Android OS के 'बिना सोर्स फ़ाइल वाली आरएसएस मेमोरी + स्वैप मेमोरी' के विकल्प के तौर पर काम करता है. इससे गेम की मेमोरी का विश्लेषण करने के लिए, कार्रवाई की जा सकने वाली अहम जानकारी मिलती है.
सीमाएं:
मेमोरी पर ज़्यादा दबाव पड़ने पर, Android OS, चालू मेमोरी पेजों को कंप्रेस या स्वैप कर सकता है, ताकि रैम को खाली किया जा सके. Unity Memory Profiler, स्वैप की गई मेमोरी को ट्रैक नहीं कर सकता. इसलिए, मेमोरी का ज़्यादा इस्तेमाल होने पर गड़बड़ियां हो सकती हैं.
Unity के वर्शन के हिसाब से, इन सुविधाओं का इस्तेमाल सीमित तौर पर किया जा सकता है.
C# स्क्रिप्ट का उदाहरण
रनटाइम के दौरान, अपने गेम की प्रोसेस की स्थिति और मेमोरी फ़ुटप्रिंट को मॉनिटर करने के तरीके के उदाहरणों के लिए, AndroidAndroidProcessStats.cs और GameMemoryMonitor.cs स्क्रिप्ट देखें.
AndroidProcessStatsस्क्रिप्ट में बताया गया है कि AndroidActivityManagerएपीआई से लिंक करने के लिए, JNI (Java Native Interface) का इस्तेमाल कैसे किया जाता है. साथ ही, इसमें चालू प्रोसेस, उनकी अहमियत, और ओएस-लेवल की स्थिति को फ़ेच करने की सुविधा मिलती है. इसमें Linux/procफ़ाइल सिस्टम से सीधे तौर पर मेमोरी के आंकड़े पढ़ने के आसान तरीके भी शामिल हैं.GameMemoryMonitorस्क्रिप्ट में बताया गया है कि इस जानकारी को लगातार मॉनिटर करने और डीबग करने के लिए कैसे हुक अप करें. इसमें यह भी बताया गया है कि परफ़ॉर्मेंस ओवरहेड को रोकने के लिए, बैकग्राउंड थ्रेड पर Android API को कैसे पोल करें. ऐसा इसलिए, क्योंकि JNI का इस्तेमाल करने और मेमोरी की जानकारी के लिए पोल करने में ज़्यादा समय लग सकता है. इसमें यह भी बताया गया है कि ऐप्लिकेशन के बैकग्राउंड में होने या फिर से शुरू होने पर, मेमोरी में होने वाले बदलावों को ट्रैक करने के लिए,OnApplicationPauseजैसे लाइफ़साइकल इवेंट में कैसे हुक अप करें.
इन टूल का इस्तेमाल करने के लिए, दोनों स्क्रिप्ट को अपने ऐसेट फ़ोल्डर में जोड़ें. इसके बाद, GameMemoryMonitor स्क्रिप्ट को अपने सीन में मौजूद किसी GameObject से अटैच करें.
ज़्यादा सटीक आकलन
Android OS की 'बिना सोर्स फ़ाइल वाली आरएसएस मेमोरी और स्वैप मेमोरी' की सटीक वैल्यू की पुष्टि करने के लिए, Perfetto का इस्तेमाल करें. इससे आपको सिस्टम-लेवल पर मेमोरी के इस्तेमाल का सटीक आकलन करने में मदद मिलती है. साथ ही, इससे आपके गेम के मेमोरी फ़ुटप्रिंट का पूरी तरह से विश्लेषण किया जा सकता है.