بهینه‌سازی حافظه بازی Unreal در اندروید

استفاده از حافظه در توسعه بازی‌های اندروید بسیار مهم است. هنگام توسعه بازی‌ها با استفاده از موتور Unreal، باید به طور مداوم وضعیت حافظه را تجزیه و تحلیل و پیگیری کنید تا این محدودیت‌های حافظه را برآورده کنید و از نشت حافظه و تخصیص بیش از حد حافظه جلوگیری کنید.

صرفه‌جویی در حافظه از طریق کاهش جایگشت سایه‌زن‌ها

با حذف گزینه‌های بلااستفاده در Lighting یا Mobile Shader Permutation Reduction ، می‌توانید تعداد جایگشت‌های سایه‌زن را به حداقل برسانید. این کار به طور قابل توجهی اندازه بسته‌بندی برنامه را کاهش می‌دهد، تعداد اشیاء حالت خط لوله (PSO) را کم می‌کند و از ایجاد اهداف رندر بلااستفاده یا بافت‌های ساختگی جلوگیری می‌کند که منجر به کاهش حافظه زمان اجرا و عملکرد بهتر می‌شود.

برای اطلاعات بیشتر، به بخش تنظیمات کاهش جایگشت سایه‌زنی و نورپردازی متفرقه برای موبایل در دستورالعمل‌های عملکرد برای دستگاه‌های موبایل مراجعه کنید.

بهینه‌سازی بارگذاری دارایی

هنگام بارگذاری دارایی‌ها با استفاده از ارجاعات سخت، محتوای متصل که حتی در بازی استفاده نمی‌شود، به طور همزمان در حافظه بارگذاری می‌شود و باعث مصرف غیرضروری حافظه می‌شود. به طور خاص، هنگامی که وراثت در طرح‌ها مورد سوءاستفاده قرار می‌گیرد، CDOهای غیرضروری (اشیاء پیش‌فرض کلاس) از والدین اختصاص داده می‌شوند و مقدار قابل توجهی از حافظه را هدر می‌دهند. در چنین مواردی، تکنیک‌های زیر را برای بهینه‌سازی استفاده از حافظه اعمال کنید.

  • تعریف کد C++ و جداسازی داده‌ها : تعریف قابلیت‌های اصلی با استفاده از UCLASS(Abstract) در کد C++ و جداسازی آنها از داده‌های واقعی.
  • به حداقل رساندن وراثت : تنظیم داده‌ها و بارگذاری دارایی‌ها را فقط در طرح‌های گره برگ انجام دهید.
  • استفاده از ارجاعات غیرمستقیم : با استفاده از TSoftObjectPtr از ارجاعات غیرمستقیم به ویژگی‌ها استفاده کنید تا از ارجاعات سخت جلوگیری شود و در زمان اجرا، در صورت نیاز، دارایی‌ها را به طور ناهمگام بارگذاری کنید.
  • اقدامات احتیاطی : هنگام استفاده از بارگذاری ناهمگام دارایی‌ها، اطمینان حاصل کنید که بررسی‌های اعتبارسنجی ( IsValid ) در طول فراخوانی تکمیل بارگذاری انجام می‌شوند تا از معلق ماندن اشاره‌گرها یا خرابی‌ها جلوگیری شود.

برای اطلاعات بیشتر، به بخش «ارجاع به دارایی‌ها و ساخت بازی‌های موبایل با UE5» مراجعه کنید.

تنظیم اشاره‌گرهای هوشمند و جمع‌آوری زباله (GC)

استفاده از اشاره‌گرهای هوشمند (مانند TSharedPtr و TWeakPtr ) در طول توسعه C++ از اشاره‌گرهای معلق و نشت حافظه جلوگیری می‌کند. علاوه بر این، استفاده از TWeakPtr از ایجاد ارجاعات قوی به اشیاء جلوگیری می‌کند، بنابراین جمع‌کننده زباله هنگام جمع‌آوری اشیاء، تعداد ارجاعات را افزایش نمی‌دهد. این امر از بقای غیرضروری اشیاء جلوگیری می‌کند و پیچیدگی گراف مرجعی را که GC باید از آن عبور کند، کاهش می‌دهد و سربار GC را به طور قابل توجهی کاهش می‌دهد. جمع‌آوری زباله را می‌توان در محیط‌های موبایل با فعال کردن ForceGarbageCollection در طول انتقال سطح یا دوره‌های عدم فعالیت، مانند زمانی که هیچ تعاملی با کاربر وجود ندارد، به طور موثر مدیریت کرد. علاوه بر این، می‌توان آن را زمانی که بازی در حالت قابل درک یا پس‌زمینه است (به عنوان مثال، فراخوانی‌های onStop ) فعال کرد و اطمینان حاصل کرد که جمع‌آوری زباله بدون تأثیر بر تجربه فعال گیم‌پلی انجام می‌شود.

برای اطلاعات بیشتر، به جمع‌آوری زباله و اشاره‌گر هوشمند مراجعه کنید.

بهینه‌سازی با استفاده از فشرده‌سازی جدول جابجایی

فشرده‌سازی جدول جابجایی (Relocation Table Compression ) یک روش بهینه‌سازی است که اندازه جدول جابجایی را در فایل‌های باینری ELF فشرده می‌کند تا اندازه باینری اندروید را کاهش دهد . وقتی نسخه minSDKVersion اندروید ۲۳ یا بالاتر باشد، فشرده‌سازی جدول جابجایی APS پشتیبانی می‌شود؛ وقتی نسخه minSDKVersion ۲۸ یا بالاتر باشد، فشرده‌سازی جدول جابجایی RELR نیز پشتیبانی می‌شود و اندازه فایل .so را به طور قابل توجهی کاهش می‌دهد. این امر نه تنها حجم دانلود را کاهش می‌دهد، بلکه ردپای حافظه mmap .so را در زمان اجرا نیز کاهش می‌دهد و فشار کلی بر حافظه فیزیکی را کاهش می‌دهد.

AndroidToolChain.cs

if (MinSDKVersion >= 28)
{
  Result += " -Wl,--pack-dyn-relocs=android+relr,--use-android-relr-tags";
}
else if (MinSDKVersion >= 23)
{
  Result += " -Wl,--pack-dyn-relocs=android";
}

برای اعمال این بهینه‌سازی، بررسی کنید که فشرده‌سازی جداول جابجایی را در تنظیمات پروژه فعال کنید یا متغیر bEnableAdvancedBinaryCompression فعال باشد.

برای بررسی اینکه آیا فشرده‌سازی RELR به درستی روی فایل باینری اعمال شده است یا خیر، از ابزار llvm-readelf از Android NDK استفاده کنید.

llvm-readelf -d libUnreal.so | grep RELR

در عمل، ساخت الگوی ThirdPerson در موتور Unreal Engine و اندازه‌گیری با استفاده از dumpsys meminfo ، کاهش استفاده از PSS و RSS را برای .so mmap تأیید می‌کند.

دسته بندی مجموع PSS خصوصی کثیف نظافت خصوصی تعویض کثیف مجموع RSS
.so mmap قبل از فشرده‌سازی ۱۷۰,۲۱۰ ۲۴,۳۶۰ ۱۴۱,۵۶۴ 0 ۲۴۲,۲۰۴
.so mmap پس از فشرده‌سازی ۱۳۸,۰۳۱ ۲۴,۷۴۸ ۱۰۸,۹۷۶ 0 ۲۱۰,۱۴۰

فشرده‌سازی بافت

از فشرده‌سازی بافت مناسب برای کاهش فضای اشغال شده توسط منابع گرافیکی کلی استفاده کنید. استفاده از فشرده‌سازی بافت مقیاس‌پذیر تطبیقی ​​(ASTC) ، استاندارد موبایل، کیفیت بصری برتر را در مقایسه با ETC2 در اندازه یکسان ارائه می‌دهد، یا با هدف کیفیت بصری یکسان، به نسبت‌های فشرده‌سازی بالاتری با مصرف حافظه کمتر دست می‌یابد.

بهینه‌سازی جریان بافت

در محیط‌های موبایل، استفاده مستقیم از اندازه پیش‌فرض مخزن جریان بافت موتور Unreal می‌تواند یک مخزن حافظه بسیار بزرگ را نسبت به مشخصات دستگاه از قبل اختصاص دهد. بنابراین، ایده‌آل این است که پروفایل‌های دستگاه موبایل را تعریف کنید و اندازه مخزن جریان بافت مناسب را با توجه به محدودیت‌های حافظه دستگاه انتخاب کنید. علاوه بر این، از ویژگی آمار ویرایشگر برای بررسی آمار بافت و شناسایی بافت‌های پرمصرف که وضوح تصویر بسیار بالایی را در زمان اجرا اشغال می‌کنند، استفاده کنید. این را با ویژگی وضوح بافت مورد نیاز ترکیب کنید تا محدودیت‌ها را اعمال کنید یا حداکثر وضوح تصویر را در بافت‌های مورد نیاز کاهش دهید و میزان استفاده از منابع را در بافر حافظه بافت اختصاص داده شده کنترل کنید.