LMKs ডিবাগ করুন

আপনার ইউনিটি গেমে এলএমকেগুলি সমাধান করা একটি পদ্ধতিগত প্রক্রিয়া:

চিত্র 1. ইউনিটি গেমগুলিতে লো মেমরি কিলস (এলএমকে) সমাধানের পদক্ষেপ।

একটি মেমরি স্ন্যাপশট প্রাপ্ত

ইউনিটি-পরিচালিত মেমরি স্ন্যাপশট পেতে ইউনিটি প্রোফাইলার ব্যবহার করুন। চিত্র 2 মেমরি ম্যানেজমেন্ট স্তর দেখায় ইউনিটি আপনার গেমে মেমরি পরিচালনা করতে ব্যবহার করে।

চিত্র 2. ইউনিটির মেমরি ব্যবস্থাপনা ওভারভিউ।

পরিচালিত স্মৃতি

ইউনিটির মেমরি ম্যানেজমেন্ট একটি নিয়ন্ত্রিত মেমরি স্তর প্রয়োগ করে যা একটি পরিচালিত গাদা এবং একটি আবর্জনা সংগ্রহকারী ব্যবহার করে মেমরি স্বয়ংক্রিয়ভাবে বরাদ্দ এবং বরাদ্দ করতে। পরিচালিত মেমরি সিস্টেম হল একটি C# স্ক্রিপ্টিং পরিবেশ যা Mono বা IL2CPP এর উপর ভিত্তি করে। পরিচালিত মেমরি সিস্টেমের সুবিধা হল যে এটি স্বয়ংক্রিয়ভাবে মেমরি বরাদ্দ মুক্ত করতে একটি আবর্জনা সংগ্রাহক ব্যবহার করে।

C# অনিয়ন্ত্রিত মেমরি

অব্যবস্থাপিত C# মেমরি স্তরটি নেটিভ মেমরি স্তরে অ্যাক্সেস সরবরাহ করে, C# কোড ব্যবহার করার সময় মেমরি বরাদ্দের উপর সুনির্দিষ্ট নিয়ন্ত্রণ সক্ষম করে। এই মেমরি ম্যানেজমেন্ট লেয়ারটি Unity.Collections namespace এবং UnsafeUtility.Malloc এবং UnsafeUtility.Free এর মতো ফাংশনের মাধ্যমে অ্যাক্সেস করা যেতে পারে।

দেশীয় স্মৃতি

ইউনিটির অভ্যন্তরীণ C/C++ কোর দৃশ্য, সম্পদ, গ্রাফিক্স API, ড্রাইভার, সাবসিস্টেম এবং প্লাগ-ইন বাফারগুলি পরিচালনা করতে একটি নেটিভ মেমরি সিস্টেম ব্যবহার করে। সরাসরি অ্যাক্সেস সীমিত থাকাকালীন, আপনি ইউনিটির C# API দিয়ে নিরাপদে ডেটা ম্যানিপুলেট করতে পারেন এবং দক্ষ নেটিভ কোড থেকে উপকৃত হতে পারেন। নেটিভ মেমরির জন্য খুব কমই সরাসরি ইন্টারঅ্যাকশনের প্রয়োজন হয়, তবে আপনি প্রোফাইলার ব্যবহার করে পারফরম্যান্সের উপর নেটিভ মেমরির প্রভাব নিরীক্ষণ করতে পারেন এবং কর্মক্ষমতা অপ্টিমাইজ করতে সেটিংস সামঞ্জস্য করতে পারেন।

চিত্র 3-এ দেখানো হিসাবে মেমরিটি C# এবং নেটিভ কোডের মধ্যে ভাগ করা হয় না। C# দ্বারা প্রয়োজনীয় ডেটা প্রতিবার প্রয়োজনে পরিচালিত মেমরি স্পেসে বরাদ্দ করা হয়।

ইঞ্জিনের নেটিভ মেমরি ডেটা অ্যাক্সেস করার জন্য পরিচালিত গেমের কোড (C#) এর জন্য, উদাহরণস্বরূপ, GameObject.transform- এ একটি কল নেটিভ এলাকায় মেমরি ডেটা অ্যাক্সেস করার জন্য একটি নেটিভ কল করে এবং তারপর Bindings ব্যবহার করে C# এ মান ফেরত দেয়। বাইন্ডিংগুলি প্রতিটি প্ল্যাটফর্মের জন্য সঠিক কলিং কনভেনশন নিশ্চিত করে এবং পরিচালিত ধরনের স্বয়ংক্রিয় মার্শালিংকে তাদের স্থানীয় সমতুল্যগুলিতে পরিচালনা করে।

এটি শুধুমাত্র প্রথমবার ঘটে, কারণ রূপান্তর সম্পত্তি অ্যাক্সেস করার জন্য পরিচালিত শেলটি নেটিভ কোডে সংরক্ষিত থাকে। ট্রান্সফর্ম প্রপার্টি ক্যাশিং করা হলে ম্যানেজড এবং নেটিভ কোডের মধ্যে পিছনে-আগামী কলের সংখ্যা কমে যেতে পারে, কিন্তু ক্যাশিংয়ের উপযোগিতা নির্ভর করে কত ঘন ঘন প্রপার্টি ব্যবহার করা হয় তার উপর। এছাড়াও, মনে রাখবেন যে আপনি যখন এই APIগুলি অ্যাক্সেস করেন তখন ইউনিটি নেটিভ মেমরির অংশগুলি পরিচালিত মেমরিতে অনুলিপি করে না।

চিত্র 3. C# পরিচালিত কোড থেকে নেটিভ মেমরি অ্যাক্সেস করা।

আরও জানতে, মেমরি ইন ইউনিটি ভূমিকা পড়ুন।

উপরন্তু, আপনার গেমটি সুচারুভাবে চলতে রাখতে একটি মেমরি বাজেট স্থাপন করা অত্যন্ত গুরুত্বপূর্ণ, এবং একটি মেমরি খরচ বিশ্লেষণ বা রিপোর্টিং সিস্টেম প্রয়োগ করা নিশ্চিত করে যে প্রতিটি নতুন রিলিজ মেমরি বাজেটের বেশি না হয়। গেমের নির্দিষ্ট ক্ষেত্রগুলিতে মেমরি খরচ যাচাই করতে আপনার ক্রমাগত ইন্টিগ্রেশন (CI) এর সাথে প্লে মোড পরীক্ষাগুলিকে একীভূত করা আরও ভাল অন্তর্দৃষ্টি অর্জনের আরেকটি কৌশল।

সম্পদ পরিচালনা করুন

এটি মেমরি খরচের সবচেয়ে প্রভাবশালী এবং কার্যকরী অংশ। যত তাড়াতাড়ি সম্ভব প্রোফাইল.

অ্যান্ড্রয়েড গেমগুলিতে মেমরির ব্যবহার গেমের ধরন, সংখ্যা এবং সম্পদের ধরন এবং মেমরি অপ্টিমাইজেশন কৌশলগুলির উপর নির্ভর করে উল্লেখযোগ্যভাবে পরিবর্তিত হতে পারে। যাইহোক, মেমরি ব্যবহারে সাধারণ অবদানকারীদের মধ্যে সাধারণত টেক্সচার, মেশ, অডিও ফাইল, শেডার, অ্যানিমেশন এবং স্ক্রিপ্ট অন্তর্ভুক্ত থাকে।

সদৃশ সম্পদ সনাক্ত করুন

প্রথম ধাপ হল মেমরি প্রোফাইলার, একটি বিল্ড রিপোর্ট টুল, বা প্রজেক্ট অডিটর ব্যবহার করে খারাপভাবে কনফিগার করা সম্পদ এবং ডুপ্লিকেট করা সম্পদ সনাক্ত করা।

টেক্সচার

আপনার গেমের ডিভাইস সমর্থন বিশ্লেষণ করুন এবং সঠিক টেক্সচার বিন্যাস নির্ধারণ করুন। আপনি Play Asset Delivery , Addressable , অথবা একটি AssetBundle সহ আরও একটি ম্যানুয়াল প্রক্রিয়া ব্যবহার করে হাই-এন্ড এবং লো-এন্ড ডিভাইসগুলির জন্য টেক্সচার বান্ডেলগুলিকে বিভক্ত করতে পারেন৷

অপ্টিমাইজ ইওর মোবাইল গেম পারফরমেন্স এবং অপ্টিমাইজিং ইউনিটি টেক্সচার ইম্পোর্ট সেটিংস আলোচনা পোস্টে উপলব্ধ সর্বাধিক পরিচিত সুপারিশগুলি অনুসরণ করুন৷ তারপর এই সমাধানগুলি চেষ্টা করুন:

  • একটি হ্রাস মেমরি ফুটপ্রিন্টের জন্য ASTC ফর্ম্যাটগুলির সাথে টেক্সচারগুলি সংকুচিত করুন এবং একটি উচ্চতর ব্লক রেট, যেমন 8x8 সহ পরীক্ষা করুন৷

    যদি ETC2 ব্যবহার করা প্রয়োজন হয়, তাহলে Atlas এ আপনার টেক্সচার প্যাক করুন। একটি একক টেক্সচারে একাধিক টেক্সচার স্থাপন করা তার পাওয়ার অফ টু (POT) নিশ্চিত করে, ড্র কল কমাতে পারে এবং রেন্ডারিংকে দ্রুত করতে পারে।

  • RenderTarget টেক্সচার বিন্যাস এবং আকার অপ্টিমাইজ করুন। অপ্রয়োজনীয়ভাবে উচ্চ-রেজোলিউশন টেক্সচার এড়িয়ে চলুন। মোবাইল ডিভাইসে ছোট টেক্সচার ব্যবহার করা মেমরি সংরক্ষণ করে।

  • টেক্সচার মেমরি সংরক্ষণ করতে টেক্সচার চ্যানেল প্যাকিং ব্যবহার করুন।

মেশ এবং মডেল

মৌলিক সেটিংস পরীক্ষা করে শুরু করুন (পৃষ্ঠা 27) এবং এই জাল আমদানি সেটিংস যাচাই করুন:

  • অপ্রয়োজনীয় এবং ছোট জাল মার্জ.
  • দৃশ্যে বস্তুর জন্য শীর্ষবিন্দু গণনা হ্রাস করুন (উদাহরণস্বরূপ, স্থির বা দূরবর্তী বস্তু)।
  • উচ্চ-জ্যামিতি সম্পদের জন্য লেভেল অফ ডিটেইল (LOD) গ্রুপ তৈরি করুন।

উপকরণ এবং shaders

  • বিল্ড প্রক্রিয়া চলাকালীন প্রোগ্রাম্যাটিকভাবে অব্যবহৃত শেডার ভেরিয়েন্ট স্ট্রিপ করুন।
  • শেডার ডুপ্লিকেশন এড়াতে প্রায়শই ব্যবহৃত শেডার ভেরিয়েন্টগুলিকে উবার শেডারে একত্রিত করুন।
  • VRAM/RAM-এ প্রিলোড করা শেডারগুলির বড় মেমরি ফুটপ্রিন্টকে অ্যাড্রেস করতে ডায়নামিক শেডার লোডিং সক্ষম করুন৷ যাইহোক, যদি শেডার সংকলন ফ্রেম হেঁচকির কারণ হয় তবে মনোযোগ দিন।
  • সমস্ত ভেরিয়েন্ট লোড হওয়া থেকে আটকাতে ডায়নামিক শেডার লোডিং ব্যবহার করুন৷ আরও তথ্যের জন্য, শেডার বিল্ড টাইম এবং মেমরি ব্যবহার ব্লগ পোস্টের উন্নতি দেখুন।
  • MaterialPropertyBlocks ব্যবহার করে সঠিকভাবে উপাদান ইন্সট্যান্সিং ব্যবহার করুন।

অডিও

মৌলিক সেটিংস পরীক্ষা করে শুরু করুন (পৃষ্ঠা 41), এবং এই জাল আমদানি সেটিংস যাচাই করুন:

  • FMOD বা Wwise-এর মতো তৃতীয় পক্ষের অডিও ইঞ্জিন নিয়োগ করার সময় অব্যবহৃত বা অপ্রয়োজনীয় AudioClip রেফারেন্সগুলি সরান৷
  • অডিও ডেটা প্রিলোড করুন। রানটাইম বা দৃশ্য স্টার্টআপের সময় অবিলম্বে প্রয়োজন হয় না এমন ক্লিপগুলির জন্য প্রিলোড অক্ষম করুন৷ এটি দৃশ্য শুরু করার সময় মেমরি ওভারহেড কমাতে সাহায্য করে।

অ্যানিমেশন

  • কীফ্রেমের সংখ্যা কমাতে এবং অপ্রয়োজনীয় ডেটা দূর করতে ইউনিটির অ্যানিমেশন কম্প্রেশন সেটিংস সামঞ্জস্য করুন।
    • কীফ্রেম হ্রাস: অপ্রয়োজনীয় কীফ্রেমগুলি স্বয়ংক্রিয়ভাবে সরিয়ে দেয়
    • Quaternion কম্প্রেশন: মেমরি ব্যবহার কমাতে ঘূর্ণন ডেটা সংকুচিত করে

আপনি রিগ বা অ্যানিমেশন ট্যাবের অধীনে অ্যানিমেশন আমদানি সেটিংসে কম্প্রেশন সেটিংস সামঞ্জস্য করতে পারেন।

  • বিভিন্ন বস্তুর জন্য অ্যানিমেশন ক্লিপ নকল করার পরিবর্তে অ্যানিমেশন ক্লিপগুলি পুনরায় ব্যবহার করুন।

    একটি অ্যানিমেটর কন্ট্রোলার পুনরায় ব্যবহার করতে এবং বিভিন্ন অক্ষরের জন্য নির্দিষ্ট ক্লিপগুলি প্রতিস্থাপন করতে অ্যানিমেটর ওভাররাইড কন্ট্রোলার ব্যবহার করুন।

  • বেক ফিজিক্স-ভিত্তিক অ্যানিমেশন: যদি আপনার অ্যানিমেশনগুলি পদার্থবিদ্যা চালিত বা পদ্ধতিগত হয়, রানটাইম গণনা এড়াতে অ্যানিমেশন ক্লিপগুলিতে সেঁকে নিন।

  • কঙ্কাল রিগ অপ্টিমাইজ করুন: জটিলতা এবং মেমরি খরচ কমাতে আপনার রিগে কম হাড় ব্যবহার করুন।

    • ছোট বা স্থির বস্তুর জন্য অতিরিক্ত হাড় এড়িয়ে চলুন।
    • যদি নির্দিষ্ট হাড়গুলি অ্যানিমেটেড না হয় বা প্রয়োজন হয়, তাহলে তাদের রিগ থেকে সরান।
  • অ্যানিমেশন ক্লিপের দৈর্ঘ্য হ্রাস করুন।

    • শুধুমাত্র প্রয়োজনীয় ফ্রেম অন্তর্ভুক্ত করার জন্য অ্যানিমেশন ক্লিপ ট্রিম করুন। অব্যবহৃত বা অত্যধিক দীর্ঘ অ্যানিমেশন সংরক্ষণ এড়িয়ে চলুন.
    • বারবার নড়াচড়ার জন্য লম্বা ক্লিপ তৈরি করার পরিবর্তে লুপিং অ্যানিমেশন ব্যবহার করুন।
  • শুধুমাত্র একটি অ্যানিমেশন উপাদান সংযুক্ত বা সক্রিয় করা হয়েছে তা নিশ্চিত করুন। উদাহরণস্বরূপ, আপনি যদি অ্যানিমেটর ব্যবহার করেন তবে লিগ্যাসি অ্যানিমেশন উপাদানগুলি অক্ষম বা সরান৷

  • অ্যানিমেটর ব্যবহার করা এড়িয়ে চলুন যদি এটি অপ্রয়োজনীয় হয়। সাধারণ ভিএফএক্সের জন্য, টুইনিং লাইব্রেরি ব্যবহার করুন বা একটি স্ক্রিপ্টে ভিজ্যুয়াল এফেক্ট প্রয়োগ করুন। অ্যানিমেটর সিস্টেম রিসোর্স ইনটেনসিভ হতে পারে, বিশেষ করে লো-এন্ড মোবাইল ডিভাইসে।

  • প্রচুর পরিমাণে অ্যানিমেশন পরিচালনা করার সময় অ্যানিমেশনের জন্য জব সিস্টেম ব্যবহার করুন, কারণ সেই সিস্টেমটি আরও মেমরি দক্ষ হওয়ার জন্য সম্পূর্ণরূপে পুনরায় ডিজাইন করা হয়েছে।

দৃশ্য

যখন নতুন দৃশ্যগুলি লোড করা হয়, তখন তারা নির্ভরতা হিসাবে সম্পদ নিয়ে আসে। যাইহোক, সঠিক সম্পদ জীবনচক্র ব্যবস্থাপনা ছাড়া, এই নির্ভরতাগুলি রেফারেন্স কাউন্টার দ্বারা নিরীক্ষণ করা হয় না। ফলস্বরূপ, অব্যবহৃত দৃশ্যগুলি আনলোড হওয়ার পরেও মেমরি ফ্র্যাগমেন্টেশনের কারণে সম্পদগুলি মেমরিতে থাকতে পারে।

  • পুনরাবৃত্ত গেমপ্লে উপাদানগুলির জন্য গেমঅবজেক্ট দৃষ্টান্তগুলি পুনঃব্যবহার করতে ইউনিটির অবজেক্ট পুলিং ব্যবহার করুন কারণ অবজেক্ট পুলিং একটি স্ট্যাক ব্যবহার করে পুনঃব্যবহারের জন্য অবজেক্ট দৃষ্টান্তের সংগ্রহ ধরে রাখে এবং থ্রেড নিরাপদ নয়। Instantiate এবং Destroy মিনিমাইজ করা CPU কর্মক্ষমতা এবং মেমরির স্থিতিশীলতা উভয়ই উন্নত করে।
  • সম্পদ আনলোড করা হচ্ছে:
    • স্প্ল্যাশ স্ক্রিন বা লোডিং স্ক্রীনের মতো কম জটিল মুহূর্তে কৌশলগতভাবে সম্পদ আনলোড করুন।
    • Resources.UnloadUnusedAssets এর ঘন ঘন ব্যবহার বড় অভ্যন্তরীণ নির্ভরতা পর্যবেক্ষণ অপারেশনের কারণে CPU প্রক্রিয়াকরণে স্পাইক ঘটায়।
    • GC.MarkDependencies প্রোফাইল মার্কারে বড় CPU স্পাইকের জন্য পরীক্ষা করুন। এটির এক্সিকিউশন ফ্রিকোয়েন্সি সরান বা কমিয়ে দিন, এবং ম্যানুয়ালি Resources.UnloadAsset ব্যবহার করার পরিবর্তে নির্দিষ্ট রিসোর্স আনলোড করুন সব-বেষ্টিত Resources.UnloadUnusedAssets() উপর নির্ভর না করে।
  • ক্রমাগত Resources.UnloadUusedAssets ব্যবহার করার পরিবর্তে দৃশ্যগুলি পুনর্গঠন করুন।
  • Addressables এর জন্য Resources.UnloadUnusedAssets() কল করা অনিচ্ছাকৃতভাবে গতিশীলভাবে লোড করা বান্ডিলগুলি আনলোড করতে পারে। গতিশীলভাবে লোড করা সম্পদের জীবনচক্র সাবধানে পরিচালনা করুন।

বিবিধ

  • দৃশ্য ট্রানজিশনের কারণে ফ্র্যাগমেন্টেশন — যখন Resources.UnloadUnusedAssets() পদ্ধতিটিকে কল করা হয়, ইউনিটি নিম্নলিখিত কাজ করে:

    • সম্পদের জন্য মেমরি মুক্ত করে যা আর ব্যবহারে নেই
    • অব্যবহৃত সম্পদের জন্য পরিচালিত এবং নেটিভ অবজেক্ট হিপ চেক করার জন্য একটি আবর্জনা সংগ্রহকারীর মতো অপারেশন চালায় এবং সেগুলি আনলোড করে
    • টেক্সচার, জাল এবং সম্পদ মেমরি পরিষ্কার করে যে কোনো সক্রিয় রেফারেন্স বিদ্যমান নেই
  • AssetBundle বা Addressable - এই ক্ষেত্রে পরিবর্তন করা জটিল এবং কৌশলগুলি বাস্তবায়নের জন্য দলের কাছ থেকে একটি সম্মিলিত প্রচেষ্টার দাবি করে৷ যাইহোক, একবার এই কৌশলগুলি আয়ত্ত করার পরে, তারা উল্লেখযোগ্যভাবে মেমরি ব্যবহার উন্নত করে, ডাউনলোডের আকার হ্রাস করে এবং ক্লাউড খরচ কম করে। সাথে ইউনিটিতে সম্পদ ব্যবস্থাপনা সম্পর্কে আরও তথ্যের জন্য, Addressables দেখুন।

  • কেন্দ্রীভূত ভাগ করা নির্ভরতা &mdash: গোষ্ঠী ভাগ করা নির্ভরতা, যেমন শেডার, টেক্সচার, এবং ফন্ট, পদ্ধতিগতভাবে ডেডিকেটেড বান্ডেল বা Addressable গোষ্ঠীতে। এটি সদৃশতা হ্রাস করে এবং নিশ্চিত করে যে অপ্রয়োজনীয় সম্পদগুলি দক্ষতার সাথে আনলোড করা হয়েছে।

  • নির্ভরতা ট্র্যাকিংয়ের জন্য Addressables ব্যবহার করুন - Addressables লোড করা সহজ করে এবং আনলোড করা স্বয়ংক্রিয়ভাবে নির্ভরতা আনলোড করতে পারে যা আর উল্লেখ করা হয় না। গেমের নির্দিষ্ট ক্ষেত্রে নির্ভর করে বিষয়বস্তু পরিচালনা এবং নির্ভরতা রেজোলিউশনের জন্য Addressables এ রূপান্তর একটি কার্যকর সমাধান হতে পারে। অপ্রয়োজনীয় ডুপ্লিকেট বা নির্ভরতা সনাক্ত করতে বিশ্লেষণ টুলের সাহায্যে নির্ভরতা চেইন বিশ্লেষণ করুন। বিকল্পভাবে, আপনি যদি AssetBundles ব্যবহার করেন তাহলে Unity Data Tools দেখুন।

  • TypeTrees - যদি আপনার গেমের Addressables এবং AssetBundles প্লেয়ারের মতো Unity-এর একই সংস্করণ ব্যবহার করে তৈরি এবং স্থাপন করা হয় এবং অন্যান্য প্লেয়ার বিল্ডগুলির সাথে পিছনের সামঞ্জস্যের প্রয়োজন না হয়, তাহলে TypeTree লেখা অক্ষম করার কথা বিবেচনা করুন, যা বান্ডিলের আকার এবং ক্রমিক ফাইল অবজেক্ট মেমরি ফুটপ্রিন্টকে হ্রাস করবে। স্থানীয় Addressables প্যাকেজ সেটিং ContentBuildFlags থেকে DisableWriteTypeTree- এ বিল্ড প্রক্রিয়া পরিবর্তন করুন।

আবর্জনা সংগ্রহকারী-বান্ধব কোড লিখুন

ইউনিটি স্বয়ংক্রিয়ভাবে অব্যবহৃত মেমরি সনাক্তকরণ এবং মুক্ত করে মেমরি পরিচালনা করতে আবর্জনা সংগ্রহ (GC) ব্যবহার করে। যদিও GC অত্যাবশ্যক, এটি সঠিকভাবে পরিচালনা না করা হলে এটি পারফরম্যান্সের সমস্যা (উদাহরণস্বরূপ, ফ্রেম রেট স্পাইক) সৃষ্টি করতে পারে, কারণ এই প্রক্রিয়াটি মুহূর্তের জন্য গেমটিকে থামিয়ে দিতে পারে, যার ফলে পারফরম্যান্স হেঁচকি এবং একটি সাবঅপ্টিমাল ব্যবহারকারীর অভিজ্ঞতা হয়।

পরিচালিত হিপ বরাদ্দের ফ্রিকোয়েন্সি হ্রাস করার জন্য দরকারী কৌশলগুলির জন্য ইউনিটি ম্যানুয়াল এবং উদাহরণের জন্য ইউনিটি পারফরম্যান্সটিউনিংবাইবেল , পৃষ্ঠা 271 দেখুন।

  • আবর্জনা সংগ্রহকারী বরাদ্দ হ্রাস করুন:

    • LINQ, lambdas এবং ক্লোজারগুলি এড়িয়ে চলুন, যা হিপ মেমরি বরাদ্দ করে।
    • স্ট্রিং কনক্যাটেনেশনের জায়গায় পরিবর্তনযোগ্য স্ট্রিংয়ের জন্য StringBuilder ব্যবহার করুন।
    • সংগ্রহগুলিকে পুনরায় ইনস্ট্যান্টিয়েট করার পরিবর্তে COLLECTIONS.Clear() কল করে পুনরায় ব্যবহার করুন৷

    প্রোফাইলিং ইউনিটি গেমস ই-বুকের জন্য আলটিমেট গাইডে আরও তথ্য পাওয়া যায়।

  • UI ক্যানভাস আপডেট পরিচালনা করুন:

    • UI উপাদানগুলিতে গতিশীল পরিবর্তন — যখন UI উপাদানগুলি যেমন পাঠ্য, চিত্র, বা RectTransform বৈশিষ্ট্যগুলি আপডেট করা হয় (উদাহরণস্বরূপ, পাঠ্য বিষয়বস্তু পরিবর্তন করা, উপাদানগুলির আকার পরিবর্তন করা, বা অ্যানিমেটিং অবস্থান), তখন ইঞ্জিন অস্থায়ী বস্তুর জন্য মেমরি বরাদ্দ করতে পারে।
    • স্ট্রিং বরাদ্দ — টেক্সটের মতো UI উপাদানগুলির জন্য প্রায়শই স্ট্রিং আপডেটের প্রয়োজন হয়, যেহেতু বেশিরভাগ প্রোগ্রামিং ভাষায় স্ট্রিংগুলি অপরিবর্তনীয়।
    • নোংরা ক্যানভাস - যখন একটি ক্যানভাসে কিছু পরিবর্তন হয় (উদাহরণস্বরূপ, উপাদানগুলিকে আকার পরিবর্তন করা, সক্রিয় করা এবং নিষ্ক্রিয় করা, বা লেআউট বৈশিষ্ট্যগুলি পরিবর্তন করা), তখন পুরো ক্যানভাস বা এর একটি অংশ নোংরা হিসাবে চিহ্নিত করা যেতে পারে এবং পুনরায় তৈরি করা যেতে পারে। এটি অস্থায়ী ডেটা স্ট্রাকচার তৈরি করতে ট্রিগার করতে পারে (উদাহরণস্বরূপ, মেশ ডেটা, ভার্টেক্স বাফার, বা লেআউট গণনা), যা আবর্জনা তৈরিতে যোগ করে।
    • সম্পূর্ণ বা ঘন ঘন আপডেট — যদি ক্যানভাসে প্রচুর পরিমাণে উপাদান থাকে বা ঘন ঘন আপডেট করা হয় (উদাহরণস্বরূপ, প্রতিটি ফ্রেম), এই পুনর্নির্মাণগুলি উল্লেখযোগ্য মেমরি মন্থন করতে পারে।
  • একাধিক ফ্রেমে বরাদ্দ ক্লিনআপ ছড়িয়ে দিয়ে বড় সংগ্রহের স্পাইক কমাতে ক্রমবর্ধমান GC সক্ষম করুন । এই বিকল্পটি আপনার গেমের কর্মক্ষমতা এবং মেমরি পদচিহ্ন উন্নত করে কিনা তা যাচাই করার জন্য প্রোফাইল৷

  • যদি আপনার গেমের একটি নিয়ন্ত্রিত পদ্ধতির প্রয়োজন হয়, আবর্জনা সংগ্রহের মোডটিকে ম্যানুয়াল তে সেট করুন৷ তারপর, একটি স্তর পরিবর্তন বা সক্রিয় গেমপ্লে ছাড়া অন্য মুহূর্তে, আবর্জনা সংগ্রহ কল.

  • গেম স্টেট ট্রানজিশনের জন্য ম্যানুয়াল আবর্জনা সংগ্রহ GC.Collect() কল করুন (উদাহরণস্বরূপ, লেভেল স্যুইচিং)।

  • সাধারণ কোড অনুশীলন থেকে শুরু করে অ্যারেগুলি অপ্টিমাইজ করুন এবং প্রয়োজনে, বড় অ্যারের জন্য নেটিভ অ্যারে বা অন্যান্য নেটিভ কন্টেনার ব্যবহার করে।

  • অব্যবস্থাপিত বস্তুর রেফারেন্সগুলি ট্র্যাক করতে ইউনিটি মেমরি প্রোফাইলারের মতো সরঞ্জামগুলি ব্যবহার করে পরিচালিত বস্তুগুলিকে নিরীক্ষণ করুন যা ধ্বংসের পরেও থাকে৷

    একটি স্বয়ংক্রিয় পদ্ধতির জন্য পারফরম্যান্স রিপোর্টিং টুলে জমা দিতে একটি প্রোফাইলার মার্কার ব্যবহার করুন।

মেমরি লিক এবং ফ্র্যাগমেন্টেশন এড়িয়ে চলুন

মেমরি লিক

C# কোডে, অবজেক্টটি ধ্বংস হয়ে যাওয়ার পরে যখন ইউনিটি অবজেক্টের একটি রেফারেন্স বিদ্যমান থাকে, তখন পরিচালিত র্যাপার অবজেক্ট, ম্যানেজড শেল নামে পরিচিত, মেমরিতে থাকে। রেফারেন্সের সাথে যুক্ত নেটিভ মেমরিটি রিলিজ করা হয় যখন দৃশ্যটি আনলোড করা হয় বা যখন গেমঅবজেক্টের সাথে মেমরিটি সংযুক্ত করা হয়, বা এর যেকোন মূল বস্তু Destroy() পদ্ধতির মাধ্যমে ধ্বংস করা হয়। যাইহোক, যদি দৃশ্য বা গেমঅবজেক্টের অন্যান্য রেফারেন্স সাফ না করা হয়, তাহলে পরিচালিত মেমরিটি একটি লিকড শেল অবজেক্ট হিসাবে টিকে থাকতে পারে । পরিচালিত শেল অবজেক্ট সম্পর্কে আরও বিশদের জন্য, পরিচালিত শেল অবজেক্ট ম্যানুয়াল দেখুন।

অতিরিক্তভাবে, ইভেন্ট সাবস্ক্রিপশন, ল্যাম্বডাস এবং ক্লোজার, স্ট্রিং কনক্যাটেনেশন এবং পুল করা বস্তুর অনুপযুক্ত ব্যবস্থাপনার কারণে মেমরি লিক হতে পারে:

  • শুরু করতে, ইউনিটি মেমরি স্ন্যাপশটগুলিকে সঠিকভাবে তুলনা করতে মেমরি লিক খুঁজুন দেখুন।
  • ইভেন্ট সদস্যতা এবং মেমরি লিক জন্য পরীক্ষা করুন. যদি অবজেক্টগুলি ইভেন্টগুলিতে সাবস্ক্রাইব করে (উদাহরণস্বরূপ, প্রতিনিধি বা ইউনিটি ইভেন্টস দ্বারা) কিন্তু ধ্বংস হওয়ার আগে সঠিকভাবে সদস্যতা ত্যাগ না করে, ইভেন্ট ম্যানেজার বা প্রকাশক সেই বস্তুগুলির রেফারেন্স ধরে রাখতে পারেন। এটি সেই বস্তুগুলিকে আবর্জনা সংগ্রহ করা থেকে বাধা দেয়, যার ফলে মেমরি লিক হয়।
  • গ্লোবাল বা সিঙ্গলটন ক্লাস ইভেন্টগুলি মনিটর করুন যেগুলি অবজেক্ট ধ্বংসের জন্য নিবন্ধিত নয়। উদাহরণ স্বরূপ, অবজেক্ট ডিস্ট্রাক্টরে প্রতিনিধিদের আনসাবস্ক্রাইব করুন বা আনহুক করুন।
  • নিশ্চিত করুন যে পুল করা বস্তুর ধ্বংস টেক্সট মেশ উপাদান , টেক্সচার এবং মূল গেমঅবজেক্টের রেফারেন্স সম্পূর্ণরূপে বাতিল করে দেয়।
  • মনে রাখবেন যে ইউনিটি মেমরি প্রোফাইলার স্ন্যাপশটগুলির তুলনা করার সময় এবং স্পষ্ট কারণ ছাড়াই মেমরি খরচের পার্থক্য পর্যবেক্ষণ করার সময়, পার্থক্যটি গ্রাফিক্স ড্রাইভার বা অপারেটিং সিস্টেমের কারণে হতে পারে।

মেমরি ফ্র্যাগমেন্টেশন

মেমরি ফ্র্যাগমেন্টেশন ঘটে যখন অনেক ছোট বরাদ্দ একটি এলোমেলো ক্রমে মুক্ত হয়। হিপ বরাদ্দ ক্রমানুসারে করা হয়, যার অর্থ হল নতুন মেমরি খণ্ড তৈরি করা হয় যখন আগের অংশের স্থান ফুরিয়ে যায়। ফলস্বরূপ, নতুন বস্তুগুলি পুরানো খণ্ডগুলির খালি জায়গাগুলি পূরণ করে না, যার ফলে খণ্ডিত হয়। উপরন্তু, বড় অস্থায়ী বরাদ্দ একটি গেমের সেশনের সময়কালের জন্য স্থায়ী খণ্ডিত হতে পারে।

এই সমস্যাটি বিশেষত সমস্যাযুক্ত যখন স্বল্পকালীন বড় বরাদ্দ দীর্ঘজীবীদের কাছে করা হয়।

তাদের জীবনকালের উপর ভিত্তি করে গ্রুপ বরাদ্দ; আদর্শভাবে, দীর্ঘস্থায়ী বরাদ্দ একসাথে করা উচিত, অ্যাপ্লিকেশনের জীবনচক্রের প্রথম দিকে।

পর্যবেক্ষক এবং ইভেন্ট ম্যানেজার

  • (Memory Leaks) 77 বিভাগে উল্লিখিত সমস্যা ছাড়াও, সময়ের সাথে সাথে, মেমরি ফাঁস অব্যবহৃত মেমরি অব্যবহৃত মেমরি বরাদ্দ রেখে যে বস্তুগুলি আর ব্যবহারে নেই সেগুলিকে ফ্র্যাগমেন্টেশনে অবদান রাখতে পারে।
  • নিশ্চিত করুন যে পুল করা বস্তুর ধ্বংস টেক্সট মেশ উপাদান , টেক্সচার এবং মূল GameObjects রেফারেন্স সম্পূর্ণরূপে বাতিল করে দেয়।
  • ইভেন্ট ম্যানেজাররা প্রায়ই ইভেন্ট সাবস্ক্রিপশন পরিচালনা করতে তালিকা বা অভিধান তৈরি করে এবং সঞ্চয় করে। রানটাইম চলাকালীন যদি এইগুলি গতিশীলভাবে বৃদ্ধি পায় এবং সঙ্কুচিত হয়, তবে ঘন ঘন বরাদ্দ এবং ডিললোকেশনের কারণে এগুলি মেমরি ফ্র্যাগমেন্টেশনে অবদান রাখতে পারে।

কোড

  • Coroutines মাঝে মাঝে মেমরি বরাদ্দ করে, যা প্রতিবার একটি নতুন ঘোষণা করার পরিবর্তে IEnumerator- এর রিটার্ন স্টেটমেন্ট ক্যাশে করে সহজেই এড়ানো যায়।
  • UnityEngine.Object ভূতের রেফারেন্স রাখা এড়াতে পুল করা বস্তুর জীবনচক্রের অবস্থা ক্রমাগত পর্যবেক্ষণ করুন।

সম্পদ

  • বহুভাষার ক্ষেত্রে সমস্ত ফন্ট প্রিলোড করা এড়াতে পাঠ্য-চালিত গেমের অভিজ্ঞতার জন্য গতিশীল ফলব্যাক সিস্টেম ব্যবহার করুন।
  • টাইপ এবং প্রত্যাশিত জীবনচক্র অনুসারে সম্পদ (উদাহরণস্বরূপ, টেক্সচার এবং কণা) সংগঠিত করুন।
  • অপ্রয়োজনীয় UI ইমেজ এবং স্ট্যাটিক মেশের মতো নিষ্ক্রিয় জীবনচক্র বৈশিষ্ট্য সহ ঘনীভূত সম্পদ।

আজীবন ভিত্তিক বরাদ্দ

  • কমপ্যাক্ট বরাদ্দ নিশ্চিত করতে অ্যাপ্লিকেশন জীবনচক্রের শুরুতে দীর্ঘস্থায়ী সম্পদ বরাদ্দ করুন।
  • মেমরি-ইনটেনসিভ বা ক্ষণস্থায়ী ডেটা স্ট্রাকচারের জন্য নেটিভ কালেকশন বা কাস্টম বরাদ্দকারী ব্যবহার করুন (উদাহরণস্বরূপ, পদার্থবিদ্যা ক্লাস্টার)।

গেম এক্সিকিউটেবল এবং প্লাগইনগুলিও মেমরি ব্যবহারকে প্রভাবিত করে।

IL2CPP মেটাডেটা

IL2CPP বিল্ড টাইমে প্রতিটি প্রকারের (উদাহরণস্বরূপ, ক্লাস, জেনেরিক এবং প্রতিনিধিদের) জন্য মেটাডেটা তৈরি করে, যা তারপরে প্রতিফলন, টাইপ চেকিং এবং অন্যান্য রানটাইম-নির্দিষ্ট ক্রিয়াকলাপের জন্য রানটাইমে ব্যবহৃত হয়। এই মেটাডেটা মেমরিতে সংরক্ষণ করা হয় এবং অ্যাপ্লিকেশনটির মোট মেমরি পদচিহ্নে উল্লেখযোগ্যভাবে অবদান রাখতে পারে। IL2CPP-এর মেটাডেটা ক্যাশে প্রারম্ভিকতা এবং লোডিং সময়ে গুরুত্বপূর্ণ অবদান রাখে। অতিরিক্তভাবে, IL2CPP নির্দিষ্ট মেটাডেটা উপাদান (উদাহরণস্বরূপ, জেনেরিক প্রকার বা সিরিয়ালাইজড তথ্য) ডিডুপ্লিকেট করে না, যার ফলে মেমরির প্রস্ফুটিত ব্যবহার হতে পারে। এটি প্রকল্পে পুনরাবৃত্তিমূলক বা অপ্রয়োজনীয় টাইপ ব্যবহারের দ্বারা বৃদ্ধি পায়।

IL2CPP মেটাডেটা কমানো যেতে পারে:

  • প্রতিফলন API- এর ব্যবহার এড়িয়ে চলুন, কারণ তারা IL2CPP মেটাডেটা বরাদ্দকরণে গুরুত্বপূর্ণ অবদান রাখতে পারে
  • অন্তর্নির্মিত প্যাকেজ নিষ্ক্রিয় করা হচ্ছে
  • ইউনিটি 2022 সম্পূর্ণ জেনেরিক শেয়ারিং বাস্তবায়ন করা, যা জেনেরিকের কারণে ওভারহেড কমাতে সাহায্য করবে। যাইহোক, বরাদ্দ আরও কমাতে সাহায্য করতে জেনেরিকের ব্যবহার কমিয়ে দিন।

কোড স্ট্রিপিং

বিল্ডের আকার কমানোর পাশাপাশি, কোড স্ট্রিপিং মেমরির ব্যবহারও হ্রাস করে। IL2CPP স্ক্রিপ্টিং ব্যাকএন্ডের বিপরীতে নির্মাণ করার সময়, পরিচালিত বাইটকোড স্ট্রিপিং (যা ডিফল্টরূপে সক্রিয় থাকে) পরিচালিত সমাবেশগুলি থেকে অব্যবহৃত কোড সরিয়ে দেয়। প্রক্রিয়াটি রুট অ্যাসেম্বলিগুলিকে সংজ্ঞায়িত করে এবং তারপরে স্ট্যাটিক কোড বিশ্লেষণ ব্যবহার করে সেই রুট অ্যাসেম্বলিগুলি ব্যবহার করে অন্য কোন পরিচালিত কোডটি নির্ধারণ করে কাজ করে। যেকোন কোড যা পৌঁছাতে পারে না তা সরানো হয়। ম্যানেজড কোড স্ট্রিপিং সম্পর্কে আরও তথ্যের জন্য, অপ্টিমাইজেশন ট্রেঞ্চস থেকে TTales দেখুন: Unity 2020 LTS ব্লগ পোস্ট এবং ম্যানেজড কোড স্ট্রিপিং ডকুমেন্টেশনের সাথে আরও ভাল পরিচালিত কোড স্ট্রিপিং।

দেশীয় বরাদ্দকারী

ফাইন-টিউন মেমরি বরাদ্দকারীর জন্য নেটিভ মেমরি বরাদ্দকারীদের সাথে পরীক্ষা করুন। গেমটির মেমরি কম থাকলে, ছোট মেমরি ব্লক ব্যবহার করুন, এমনকি এতে ধীরগতির বরাদ্দকারী জড়িত থাকলেও। আরও জানতে ডায়নামিক হিপ অ্যালোকেটর উদাহরণ দেখুন।

নেটিভ প্লাগইন এবং SDK পরিচালনা করুন

  • সমস্যাযুক্ত প্লাগইন খুঁজুন — প্রতিটি প্লাগইন সরান এবং গেম মেমরি স্ন্যাপশট তুলনা করুন। এতে স্ক্রিপ্টিং ডিফাইন সিম্বল সহ প্রচুর কোড কার্যকারিতা নিষ্ক্রিয় করা এবং ইন্টারফেসের সাথে উচ্চ মিলিত ক্লাস রিফ্যাক্টর করা জড়িত। আপনার গেমটিকে খেলার অযোগ্য না করে বাহ্যিক নির্ভরতা নিষ্ক্রিয় করার প্রক্রিয়াটিকে সহজতর করতে গেম প্রোগ্রামিং প্যাটার্ন সহ আপনার কোডের স্তরটি পরীক্ষা করুন৷

  • প্লাগইন বা SDK লেখকের সাথে যোগাযোগ করুন — বেশিরভাগ প্লাগইন ওপেন সোর্স নয়।

  • প্লাগইন মেমরি ব্যবহার পুনরুত্পাদন করুন — আপনি একটি সাধারণ প্লাগইন লিখতে পারেন (রেফারেন্স হিসাবে এই ইউনিটি প্লাগইনটি ব্যবহার করুন) যা মেমরি বরাদ্দ করে। অ্যান্ড্রয়েড স্টুডিও ব্যবহার করে মেমরি স্ন্যাপশটগুলি পরিদর্শন করুন (যেহেতু ইউনিটি এই বরাদ্দগুলি ট্র্যাক করে না) বা একই প্রকল্পে MemoryInfo ক্লাস এবং Runtime.totalMemory() পদ্ধতিতে কল করুন৷

একটি ইউনিটি প্লাগইন জাভা এবং নেটিভ মেমরি বরাদ্দ করে; এটি কিভাবে করতে হয় তা এখানে:

জাভা

byte[] largeObject = new byte[1024 * 1024 * megaBytes];
list.add(largeObject);

নেটিভ

char* buffer = new char[megabytes * 1024 * 1024];

// Random data to fill the buffer
for (int i = 1; i < megabytes * 1024 * 1024; ++i) {
   buffer[i] = 'A' + (i % 26); // Fill with letters A-Z
}