মেমরি প্রোফাইলারের সাথে আপনার অ্যাপের মেমরি ব্যবহার পরিদর্শন করুন৷

মেমরি প্রোফাইলার হল অ্যান্ড্রয়েড প্রোফাইলারের একটি উপাদান যা আপনাকে মেমরি ফাঁস এবং মেমরি মন্থন শনাক্ত করতে সাহায্য করে যা তোতলা, জমে যাওয়া এবং এমনকি অ্যাপ ক্র্যাশ হতে পারে। এটি আপনার অ্যাপের মেমরি ব্যবহারের একটি রিয়েলটাইম গ্রাফ দেখায় এবং আপনাকে একটি হিপ ডাম্প, জোর করে আবর্জনা সংগ্রহ এবং মেমরি বরাদ্দ ট্র্যাক করতে দেয়।

মেমরি প্রোফাইলার খুলতে, এই পদক্ষেপগুলি অনুসরণ করুন:

  1. View > Tool Windows > Profiler এ ক্লিক করুন (আপনি প্রোফাইলেও ক্লিক করতে পারেন টুলবারে)।
  2. অ্যান্ড্রয়েড প্রোফাইলার টুলবার থেকে আপনি প্রোফাইল করতে চান এমন ডিভাইস এবং অ্যাপ প্রক্রিয়া নির্বাচন করুন। আপনি যদি USB এর মাধ্যমে একটি ডিভাইস সংযুক্ত করে থাকেন কিন্তু এটি তালিকাভুক্ত দেখতে না পান, তাহলে নিশ্চিত করুন যে আপনি USB ডিবাগিং সক্ষম করেছেন
  3. মেমরি প্রোফাইলার খুলতে মেমরি টাইমলাইনের যে কোন জায়গায় ক্লিক করুন।

বিকল্পভাবে, আপনি কমান্ড লাইন থেকে আপনার অ্যাপ মেমরি পরীক্ষা করতে পারেন ডাম্পসিস দিয়ে, এবং এছাড়াও logcat-এ GC ইভেন্টগুলি দেখতে পারেন

কেন আপনি আপনার অ্যাপ মেমরি প্রোফাইল করা উচিত

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

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

এই সমস্যাগুলি প্রতিরোধ করতে, আপনাকে নিম্নলিখিতগুলি করতে মেমরি প্রোফাইলার ব্যবহার করা উচিত:

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

আপনার অ্যাপের মেমরি ব্যবহার কমাতে পারে এমন প্রোগ্রামিং অনুশীলন সম্পর্কে তথ্যের জন্য, আপনার অ্যাপের মেমরি পরিচালনা করুন পড়ুন।

মেমরি প্রোফাইলার ওভারভিউ

আপনি যখন প্রথম মেমরি প্রোফাইলার খুলবেন, তখন আপনি আপনার অ্যাপের মেমরি ব্যবহারের একটি বিশদ টাইমলাইন দেখতে পাবেন এবং জোর করে আবর্জনা সংগ্রহ করতে, একটি হিপ ডাম্প ক্যাপচার করতে এবং মেমরি বরাদ্দ রেকর্ড করতে সরঞ্জামগুলি অ্যাক্সেস করতে পারবেন৷

চিত্র 1. মেমরি প্রোফাইলার

চিত্র 1 এ নির্দেশিত হিসাবে, মেমরি প্রোফাইলারের ডিফল্ট ভিউতে নিম্নলিখিতগুলি অন্তর্ভুক্ত রয়েছে:

  1. একটি আবর্জনা সংগ্রহ ইভেন্ট জোর করে একটি বোতাম.
  2. একটি হিপ ডাম্প ক্যাপচার করার জন্য একটি বোতাম৷

    দ্রষ্টব্য: Android 7.1 (API লেভেল 25) বা তার নিচের চলমান ডিভাইসের সাথে কানেক্ট করা হলেই মেমরি বরাদ্দ রেকর্ড করার জন্য একটি বোতাম হিপ ডাম্প বোতামের ডানদিকে প্রদর্শিত হয়।

  3. প্রোফাইলার কত ঘন ঘন মেমরি বরাদ্দ ক্যাপচার করে তা নির্দিষ্ট করার জন্য একটি ড্রপডাউন মেনু। উপযুক্ত বিকল্প নির্বাচন করা আপনাকে প্রোফাইল করার সময় অ্যাপের কর্মক্ষমতা উন্নত করতে সাহায্য করতে পারে।
  4. টাইমলাইনে জুম ইন/আউট করার বোতাম।
  5. লাইভ মেমরি ডেটাতে এগিয়ে যাওয়ার জন্য একটি বোতাম।
  6. ইভেন্ট টাইমলাইন, যা অ্যাক্টিভিটি স্টেট, ইউজার ইনপুট ইভেন্ট এবং স্ক্রিন রোটেশন ইভেন্ট দেখায়।
  7. মেমরি টাইমলাইন ব্যবহার করে, যার মধ্যে নিম্নলিখিতগুলি রয়েছে:
    • প্রতিটি মেমরি বিভাগ দ্বারা কত মেমরি ব্যবহার করা হচ্ছে তার একটি স্ট্যাক করা গ্রাফ, বাম দিকের y-অক্ষ এবং উপরে রঙ কী দ্বারা নির্দেশিত৷
    • একটি ড্যাশড লাইন বরাদ্দকৃত বস্তুর সংখ্যা নির্দেশ করে, যেমনটি ডানদিকে y-অক্ষ দ্বারা নির্দেশিত।
    • প্রতিটি আবর্জনা সংগ্রহ ইভেন্টের জন্য একটি আইকন।

যাইহোক, আপনি যদি Android 7.1 বা তার কম সংস্করণে চলমান একটি ডিভাইস ব্যবহার করেন, তবে সমস্ত প্রোফাইলিং ডেটা ডিফল্টরূপে দৃশ্যমান হয় না। আপনি যদি এমন একটি বার্তা দেখতে পান যা বলে, "নির্বাচিত প্রক্রিয়ার জন্য উন্নত প্রোফাইলিং অনুপলব্ধ," আপনাকে নিম্নলিখিতগুলি দেখতে উন্নত প্রোফাইলিং সক্ষম করতে হবে:

  • ইভেন্ট টাইমলাইন
  • বরাদ্দকৃত বস্তুর সংখ্যা
  • আবর্জনা সংগ্রহের ঘটনা

অ্যান্ড্রয়েড 8.0 এবং উচ্চতর সংস্করণে, ডিবাগযোগ্য অ্যাপগুলির জন্য সর্বদা উন্নত প্রোফাইলিং সক্ষম করা হয়৷

কিভাবে মেমরি গণনা করা হয়

মেমরি প্রোফাইলার (চিত্র 2) এর শীর্ষে আপনি যে সংখ্যাগুলি দেখতে পাচ্ছেন তা অ্যান্ড্রয়েড সিস্টেম অনুসারে আপনার অ্যাপের প্রতিশ্রুতিবদ্ধ সমস্ত ব্যক্তিগত মেমরি পৃষ্ঠাগুলির উপর ভিত্তি করে। এই গণনায় সিস্টেম বা অন্যান্য অ্যাপের সাথে শেয়ার করা পৃষ্ঠাগুলি অন্তর্ভুক্ত নয়।

চিত্র 2. মেমরি প্রোফাইলারের শীর্ষে মেমরি গণনা কিংবদন্তি

মেমরি কাউন্টের বিভাগগুলি নিম্নরূপ:

  • জাভা : জাভা বা কোটলিন কোড থেকে বরাদ্দ করা বস্তুর মেমরি।
  • নেটিভ : C বা C++ কোড থেকে বরাদ্দ করা বস্তুর মেমরি।

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

  • গ্রাফিক্স : জিএল সারফেস, জিএল টেক্সচার ইত্যাদি সহ স্ক্রিনে পিক্সেল প্রদর্শনের জন্য গ্রাফিক্স বাফার সারিগুলির জন্য ব্যবহৃত মেমরি। (মনে রাখবেন যে এটি CPU-এর সাথে ভাগ করা মেমরি, ডেডিকেটেড GPU মেমরি নয়।)

  • স্ট্যাক : আপনার অ্যাপে নেটিভ এবং জাভা উভয় স্ট্যাক দ্বারা ব্যবহৃত মেমরি। এটি সাধারণত আপনার অ্যাপটি কতগুলি থ্রেড চলছে তার সাথে সম্পর্কিত।

  • কোড : মেমরি যা আপনার অ্যাপ কোড এবং সংস্থানগুলির জন্য ব্যবহার করে, যেমন ডেক্স বাইটকোড, অপ্টিমাইজ করা বা সংকলিত ডেক্স কোড, .so লাইব্রেরি এবং ফন্ট।

  • অন্যান্য : আপনার অ্যাপ দ্বারা ব্যবহৃত মেমরি যেটি কীভাবে শ্রেণিবদ্ধ করতে হবে তা সিস্টেম নিশ্চিত নয়৷

  • বরাদ্দকৃত : আপনার অ্যাপ দ্বারা বরাদ্দকৃত জাভা/কোটলিন বস্তুর সংখ্যা। এটি C বা C++ এ বরাদ্দকৃত বস্তু গণনা করে না।

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

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

মেমরি বরাদ্দ দেখুন

মেমরি বরাদ্দ আপনাকে দেখায় কিভাবে আপনার মেমরিতে প্রতিটি জাভা অবজেক্ট এবং JNI রেফারেন্স বরাদ্দ করা হয়েছিল। বিশেষত, মেমরি প্রোফাইলার আপনাকে বস্তু বরাদ্দ সম্পর্কে নিম্নলিখিত দেখাতে পারে:

  • কি ধরনের বস্তু বরাদ্দ করা হয়েছিল এবং তারা কতটা জায়গা ব্যবহার করে।
  • কোন থ্রেড সহ প্রতিটি বরাদ্দের স্ট্যাক ট্রেস।
  • যখন বস্তুগুলিকে ডিললোকেড করা হয়েছিল (কেবলমাত্র যখন Android 8.0 বা উচ্চতর ডিভাইস ব্যবহার করে)।

জাভা এবং কোটলিন বরাদ্দ রেকর্ড করতে, রেকর্ড জাভা / কোটলিন বরাদ্দ নির্বাচন করুন, তারপর রেকর্ড নির্বাচন করুন। ডিভাইসটি যদি অ্যান্ড্রয়েড 8 বা উচ্চতর চলমান থাকে, তবে মেমরি প্রোফাইলার UI চলমান রেকর্ডিং প্রদর্শন করে একটি পৃথক স্ক্রিনে রূপান্তরিত হয়। আপনি রেকর্ডিংয়ের উপরে মিনি টাইমলাইনের সাথে ইন্টারঅ্যাক্ট করতে পারেন (উদাহরণস্বরূপ, নির্বাচনের পরিসর পরিবর্তন করতে)। রেকর্ডিং সম্পূর্ণ করতে, থামুন নির্বাচন করুন .

মেমরি প্রোফাইলারে জাভা বরাদ্দের ভিজ্যুয়ালাইজেশন

অ্যান্ড্রয়েড 7.1 এবং তার নিচের সংস্করণে, মেমরি প্রোফাইলার লিগ্যাসি অ্যালোকেশন রেকর্ডিং ব্যবহার করে, যা আপনি থামুন ক্লিক না করা পর্যন্ত টাইমলাইনে রেকর্ডিং প্রদর্শন করে।

আপনি টাইমলাইনের একটি অঞ্চল নির্বাচন করার পরে (অথবা আপনি যখন Android 7.1 বা তার নিচের সংস্করণে চালিত একটি ডিভাইসের সাথে একটি রেকর্ডিং সেশন শেষ করেন), বরাদ্দকৃত বস্তুর তালিকা প্রদর্শিত হবে, শ্রেণির নাম অনুসারে গোষ্ঠীবদ্ধ এবং তাদের হিপ গণনা অনুসারে সাজানো হয়েছে।

বরাদ্দ রেকর্ড পরিদর্শন করতে, এই পদক্ষেপগুলি অনুসরণ করুন:

  1. অস্বাভাবিকভাবে বড় হিপ কাউন্ট আছে এবং যেগুলি ফাঁস হতে পারে এমন বস্তুগুলি খুঁজে পেতে তালিকাটি ব্রাউজ করুন৷ পরিচিত ক্লাসগুলি খুঁজে পেতে সাহায্য করতে, বর্ণানুক্রমিকভাবে সাজানোর জন্য ক্লাসের নাম কলাম শিরোনামে ক্লিক করুন। তারপর একটি ক্লাস নাম ক্লিক করুন. ইনস্ট্যান্স ভিউ ফলকটি ডানদিকে প্রদর্শিত হয়, সেই ক্লাসের প্রতিটি উদাহরণ দেখায়, যেমন চিত্র 3-এ দেখানো হয়েছে।
    • বিকল্পভাবে, আপনি ফিল্টার ক্লিক করে দ্রুত বস্তুগুলি সনাক্ত করতে পারেন , অথবা কন্ট্রোল+এফ (ম্যাকে কমান্ড+এফ) টিপে এবং অনুসন্ধান ক্ষেত্রে একটি ক্লাস বা প্যাকেজের নাম প্রবেশ করান। আপনি যদি ড্রপডাউন মেনু থেকে কলস্ট্যাক দ্বারা সাজান নির্বাচন করেন তবে আপনি পদ্ধতির নাম দ্বারা অনুসন্ধান করতে পারেন। আপনি যদি রেগুলার এক্সপ্রেশন ব্যবহার করতে চান, তাহলে Regex- এর পাশের বাক্সটি চেক করুন। আপনার অনুসন্ধান ক্যোয়ারী কেস-সংবেদনশীল হলে ম্যাচ কেস এর পাশের বাক্সে টিক চিহ্ন দিন।
  2. ইনস্ট্যান্স ভিউ প্যানে, একটি উদাহরণে ক্লিক করুন। কল স্ট্যাক ট্যাবটি নীচে প্রদর্শিত হবে, যেখানে সেই দৃষ্টান্তটি বরাদ্দ করা হয়েছে এবং কোন থ্রেডে দেখানো হয়েছে।
  3. কল স্ট্যাক ট্যাবে, যেকোন লাইনে ডান-ক্লিক করুন এবং সম্পাদকে সেই কোডটি খুলতে উৎসে জাম্প নির্বাচন করুন।

চিত্র 3. প্রতিটি বরাদ্দকৃত বস্তুর বিশদ বিবরণ ডানদিকে ইনস্ট্যান্স ভিউতে প্রদর্শিত হবে

কোন স্তূপ পরিদর্শন করতে হবে এবং কীভাবে ডেটা সংগঠিত করতে হবে তা চয়ন করতে আপনি বরাদ্দকৃত বস্তুর তালিকার উপরের দুটি মেনু ব্যবহার করতে পারেন।

বাম দিকের মেনু থেকে, কোন গাদাটি পরিদর্শন করতে হবে তা চয়ন করুন:

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

ডানদিকের মেনু থেকে, বরাদ্দগুলি কীভাবে সাজানো যায় তা চয়ন করুন:

  • শ্রেণী অনুসারে সাজান : শ্রেণীর নামের উপর ভিত্তি করে সমস্ত বরাদ্দ গোষ্ঠী করে। এটি ডিফল্ট।
  • প্যাকেজ অনুসারে সাজান : প্যাকেজের নামের উপর ভিত্তি করে সমস্ত বরাদ্দ গ্রুপ করে।
  • কলস্ট্যাক দ্বারা সাজান : সমস্ত বরাদ্দকে তাদের সংশ্লিষ্ট কল স্ট্যাকের মধ্যে গোষ্ঠীবদ্ধ করুন।

প্রোফাইলিং করার সময় অ্যাপের কর্মক্ষমতা উন্নত করুন

প্রোফাইলিং করার সময় অ্যাপের কর্মক্ষমতা উন্নত করতে, মেমরি প্রোফাইলার ডিফল্টভাবে পর্যায়ক্রমে মেমরি বরাদ্দের নমুনা দেয়। API স্তর 26 বা উচ্চতর চলমান ডিভাইসগুলিতে পরীক্ষা করার সময়, আপনি বরাদ্দ ট্র্যাকিং ড্রপডাউন ব্যবহার করে এই আচরণটি পরিবর্তন করতে পারেন। উপলব্ধ বিকল্পগুলি নিম্নরূপ:

  • সম্পূর্ণ : মেমরিতে সমস্ত বস্তু বরাদ্দ ক্যাপচার করে। এটি অ্যান্ড্রয়েড স্টুডিও 3.2 এবং তার আগের ডিফল্ট আচরণ। আপনার যদি এমন একটি অ্যাপ থাকে যা অনেকগুলি বস্তু বরাদ্দ করে, আপনি প্রোফাইল করার সময় আপনার অ্যাপের সাথে দৃশ্যমান মন্থরতা লক্ষ্য করতে পারেন।
  • নমুনা : নিয়মিত বিরতিতে মেমরিতে বস্তুর বরাদ্দের নমুনা। এটি ডিফল্ট বিকল্প এবং প্রোফাইল করার সময় অ্যাপের কার্যক্ষমতার উপর কম প্রভাব ফেলে। যে অ্যাপগুলি অল্প সময়ের মধ্যে অনেকগুলি বস্তু বরাদ্দ করে সেগুলি এখনও দৃশ্যমান মন্থরতা প্রদর্শন করতে পারে৷
  • বন্ধ : আপনার অ্যাপের মেমরি বরাদ্দ ট্র্যাক করা বন্ধ করে।

বিশ্বব্যাপী JNI রেফারেন্স দেখুন

জাভা নেটিভ ইন্টারফেস (জেএনআই) হল একটি ফ্রেমওয়ার্ক যা জাভা কোড এবং নেটিভ কোড একে অপরকে কল করতে দেয়।

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

এই ধরনের সমস্যা সমাধানের জন্য, সমস্ত গ্লোবাল জেএনআই রেফারেন্স ব্রাউজ করতে এবং জাভা প্রকার এবং নেটিভ কল স্ট্যাক দ্বারা ফিল্টার করতে মেমরি প্রোফাইলারে JNI হিপ ভিউ ব্যবহার করুন। এই তথ্যের সাহায্যে, আপনি জানতে পারবেন কখন এবং কোথায় বিশ্বব্যাপী JNI রেফারেন্স তৈরি এবং মুছে ফেলা হয়।

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

চিত্র 4. বিশ্বব্যাপী JNI রেফারেন্স দেখা

আপনার অ্যাপের JNI কোডের জন্য মেমরি বরাদ্দ পরিদর্শন করতে, আপনাকে অবশ্যই Android 8.0 বা উচ্চতর চলমান ডিভাইসে আপনার অ্যাপ স্থাপন করতে হবে।

JNI সম্পর্কে আরও তথ্যের জন্য, JNI টিপস দেখুন।

নেটিভ মেমরি প্রোফাইলার

অ্যান্ড্রয়েড স্টুডিও মেমরি প্রোফাইলারে অ্যান্ড্রয়েড 10 এবং উচ্চতর সংস্করণে চলমান ভৌত এবং ভার্চুয়াল ডিভাইসগুলিতে স্থাপন করা অ্যাপগুলির জন্য একটি নেটিভ মেমরি প্রোফাইলার অন্তর্ভুক্ত রয়েছে।

নেটিভ মেমরি প্রোফাইলার একটি নির্দিষ্ট সময়ের জন্য নেটিভ কোডে বস্তুর বরাদ্দ/বরাদ্দকরণ ট্র্যাক করে এবং নিম্নলিখিত তথ্য প্রদান করে:

  • বরাদ্দকরণ: নির্বাচিত সময়ের মধ্যে malloc() বা new অপারেটরের মাধ্যমে বরাদ্দকৃত বস্তুর গণনা।
  • ডিঅ্যালোকেশন: নির্বাচিত সময়ের মধ্যে free() বা delete অপারেটরের মাধ্যমে ডিললোকেড করা বস্তুর একটি গণনা।
  • বরাদ্দের আকার: নির্বাচিত সময়ের মধ্যে সমস্ত বরাদ্দের বাইটে একত্রিত আকার।
  • ডিঅ্যালোকেশন সাইজ: নির্বাচিত সময়ের মধ্যে সমস্ত মুক্ত মেমরির বাইটে একত্রিত আকার।
  • মোট গণনা: বরাদ্দ কলামের মান বিয়োগ ডিঅ্যালোকেশন কলামের মান।
  • অবশিষ্ট আকার: বরাদ্দের আকার কলামের মান ডিঅ্যালোকেশন সাইজ কলামের মান বিয়োগ করে।

নেটিভ মেমরি প্রোফাইলার

Android 10 এবং উচ্চতর ডিভাইসে চলমান ডিভাইসগুলিতে নেটিভ বরাদ্দ রেকর্ড করতে, নেটিভ বরাদ্দ রেকর্ড করুন নির্বাচন করুন, তারপরে রেকর্ড নির্বাচন করুন। আপনি থামে ক্লিক না করা পর্যন্ত রেকর্ডিং চলতে থাকবে , এর পরে মেমরি প্রোফাইলার UI একটি পৃথক স্ক্রিনে রূপান্তরিত হয় যা নেটিভ রেকর্ডিং প্রদর্শন করে।

রেকর্ড নেটিভ বরাদ্দ বোতাম

অ্যান্ড্রয়েড 9 এবং তার পরে, রেকর্ড নেটিভ অ্যালোকেশন বিকল্পটি উপলব্ধ নেই।

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

নেটিভ মেমরি প্রোফাইলারের নমুনা আকার পরিবর্তন করতে:

  1. রান > কনফিগারেশন সম্পাদনা নির্বাচন করুন।
  2. বাম ফলকে আপনার অ্যাপ মডিউল নির্বাচন করুন।
  3. প্রোফাইলিং ট্যাবে ক্লিক করুন, এবং নেটিভ মেমরি স্যাম্পলিং ইন্টারভাল (বাইট) লেবেলযুক্ত ক্ষেত্রে নমুনার আকার লিখুন।
  4. আবার আপনার অ্যাপ তৈরি করুন এবং চালান।

একটি গাদা ডাম্প ক্যাপচার

একটি হিপ ডাম্প দেখায় যে আপনি হিপ ডাম্প ক্যাপচার করার সময় আপনার অ্যাপের কোন বস্তু মেমরি ব্যবহার করছে। বিশেষ করে একটি বর্ধিত ব্যবহারকারীর সেশনের পরে, একটি হিপ ডাম্প মেমরিতে থাকা বস্তুগুলি দেখিয়ে মেমরি লিক সনাক্ত করতে সাহায্য করতে পারে যা আপনি মনে করেন যে সেখানে আর থাকা উচিত নয়।

আপনি একটি গাদা ডাম্প ক্যাপচার করার পরে, আপনি নিম্নলিখিত দেখতে পারেন:

  • আপনার অ্যাপ কি ধরনের অবজেক্ট বরাদ্দ করেছে এবং প্রতিটির কতটি।
  • প্রতিটি বস্তু কত মেমরি ব্যবহার করছে।
  • যেখানে প্রতিটি বস্তুর রেফারেন্স আপনার কোডে রাখা হচ্ছে।
  • কল স্ট্যাক যেখানে একটি বস্তু বরাদ্দ করা হয়েছিল। (অ্যালোকেশন রেকর্ড করার সময় আপনি হিপ ডাম্প ক্যাপচার করার সময় কল স্ট্যাকগুলি বর্তমানে শুধুমাত্র Android 7.1 এবং তার নিচের সংস্করণে একটি হিপ ডাম্পের সাথে উপলব্ধ৷)

একটি হিপ ডাম্প ক্যাপচার করতে, ক্যাপচার হিপ ডাম্প ক্লিক করুন, তারপর রেকর্ড নির্বাচন করুন। গাদা ডাম্প করার সময়, জাভা মেমরির পরিমাণ সাময়িকভাবে বাড়তে পারে। এটি স্বাভাবিক কারণ হিপ ডাম্প আপনার অ্যাপের মতো একই প্রক্রিয়ায় ঘটে এবং ডেটা সংগ্রহ করতে কিছু মেমরির প্রয়োজন হয়।

প্রোফাইলার হিপ ডাম্প ক্যাপচার করা শেষ করার পরে, মেমরি প্রোফাইলার UI হিপ ডাম্প প্রদর্শন করে একটি পৃথক স্ক্রিনে রূপান্তরিত হয়।

চিত্র 5. গাদা ডাম্প দেখা।

কখন ডাম্প তৈরি করা হয় সে সম্পর্কে আপনার যদি আরও সুনির্দিষ্ট হতে হয়, তাহলে আপনি dumpHprofData() কল করে আপনার অ্যাপ কোডের গুরুত্বপূর্ণ পয়েন্টে একটি হিপ ডাম্প তৈরি করতে পারেন।

ক্লাসের তালিকায়, আপনি নিম্নলিখিত তথ্য দেখতে পারেন:

  • বরাদ্দ : গাদা মধ্যে বরাদ্দ সংখ্যা.
  • নেটিভ সাইজ : এই অবজেক্ট টাইপ দ্বারা ব্যবহৃত মোট নেটিভ মেমরি (বাইটে)। এই কলামটি শুধুমাত্র Android 7.0 এবং উচ্চতর সংস্করণের জন্য দৃশ্যমান।

    আপনি এখানে জাভাতে বরাদ্দ করা কিছু বস্তুর জন্য মেমরি দেখতে পাবেন কারণ অ্যান্ড্রয়েড কিছু ফ্রেমওয়ার্ক ক্লাসের জন্য নেটিভ মেমরি ব্যবহার করে, যেমন Bitmap

  • অগভীর আকার : এই অবজেক্ট টাইপ দ্বারা ব্যবহৃত জাভা মেমরির মোট পরিমাণ (বাইটে)।

  • ধরে রাখা মাপ : এই শ্রেণীর (বাইটে) সমস্ত দৃষ্টান্তের কারণে মেমরির মোট আকার রাখা হচ্ছে।

কোন হিপ ডাম্পগুলি পরিদর্শন করতে হবে এবং কীভাবে ডেটা সংগঠিত করতে হবে তা চয়ন করতে আপনি বরাদ্দ করা বস্তুর তালিকার উপরের দুটি মেনু ব্যবহার করতে পারেন।

বাম দিকের মেনু থেকে, কোন গাদাটি পরিদর্শন করতে হবে তা চয়ন করুন:

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

ডানদিকের মেনু থেকে, বরাদ্দগুলি কীভাবে সাজানো যায় তা চয়ন করুন:

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

তালিকাটি ডিফল্টরূপে ধরে রাখা আকার কলাম দ্বারা বাছাই করা হয়। একটি ভিন্ন কলামে মান অনুসারে সাজানোর জন্য, কলামের শিরোনামে ক্লিক করুন।

ডানদিকে ইনস্ট্যান্স ভিউ উইন্ডো খুলতে একটি ক্লাসের নামে ক্লিক করুন (চিত্র 6-এ দেখানো হয়েছে)। প্রতিটি তালিকাভুক্ত উদাহরণ নিম্নলিখিত অন্তর্ভুক্ত:

  • গভীরতা : যেকোন GC রুট থেকে নির্বাচিত দৃষ্টান্ত পর্যন্ত হপগুলির সংক্ষিপ্ত সংখ্যক।
  • নেটিভ সাইজ : নেটিভ মেমরিতে এই উদাহরণের আকার। এই কলামটি শুধুমাত্র Android 7.0 এবং উচ্চতর সংস্করণের জন্য দৃশ্যমান।
  • অগভীর আকার : জাভা মেমরিতে এই উদাহরণের আকার।
  • ধরে রাখা আকার : মেমরির আকার যা এই উদাহরণটি প্রাধান্য দেয় ( ডোমিনেটর ট্রি অনুসারে)।

চিত্র 6. একটি হিপ ডাম্প ক্যাপচার করার জন্য প্রয়োজনীয় সময়কাল টাইমলাইনে নির্দেশিত হয়েছে৷

আপনার স্তূপ পরিদর্শন করতে, এই পদক্ষেপগুলি অনুসরণ করুন:

  1. অস্বাভাবিকভাবে বড় হিপ কাউন্ট আছে এবং যেগুলি ফাঁস হতে পারে এমন বস্তুগুলি খুঁজে পেতে তালিকাটি ব্রাউজ করুন৷ পরিচিত ক্লাস খুঁজে পেতে সাহায্য করতে, বর্ণানুক্রমিকভাবে সাজানোর জন্য ক্লাসের নাম কলামের শিরোনামে ক্লিক করুন। তারপর একটি ক্লাস নাম ক্লিক করুন. ইনস্ট্যান্স ভিউ ফলকটি ডানদিকে প্রদর্শিত হবে, সেই ক্লাসের প্রতিটি দৃষ্টান্ত দেখাচ্ছে, যেমন চিত্র 6 এ দেখানো হয়েছে।
    • বিকল্পভাবে, আপনি ফিল্টার ক্লিক করে দ্রুত বস্তুগুলি সনাক্ত করতে পারেন , অথবা কন্ট্রোল+এফ (ম্যাকে কমান্ড+এফ) টিপে এবং অনুসন্ধান ক্ষেত্রে একটি ক্লাস বা প্যাকেজের নাম প্রবেশ করান। আপনি যদি ড্রপডাউন মেনু থেকে কলস্ট্যাক দ্বারা সাজান নির্বাচন করেন তবে আপনি পদ্ধতির নাম দ্বারা অনুসন্ধান করতে পারেন। আপনি যদি রেগুলার এক্সপ্রেশন ব্যবহার করতে চান, তাহলে Regex- এর পাশের বাক্সটি চেক করুন। আপনার অনুসন্ধান ক্যোয়ারী কেস-সংবেদনশীল হলে ম্যাচ কেস এর পাশের বাক্সে টিক চিহ্ন দিন।
  2. ইনস্ট্যান্স ভিউ প্যানে, একটি উদাহরণে ক্লিক করুন। রেফারেন্স ট্যাব নীচে প্রদর্শিত হবে, যে বস্তুর প্রতিটি রেফারেন্স দেখাচ্ছে।

    অথবা, ইনস্ট্যান্স নামের পাশের তীরটিতে ক্লিক করুন এর সমস্ত ক্ষেত্র দেখতে, এবং তারপর একটি ক্ষেত্রের নাম ক্লিক করুন এর সমস্ত রেফারেন্স দেখতে। আপনি যদি একটি ক্ষেত্রের জন্য দৃষ্টান্তের বিবরণ দেখতে চান, ক্ষেত্রের উপর ডান-ক্লিক করুন এবং ইনস্ট্যান্সে যান নির্বাচন করুন।

  3. রেফারেন্স ট্যাবে, আপনি যদি এমন একটি রেফারেন্স সনাক্ত করেন যা মেমরি ফাঁস হতে পারে, এটিতে ডান-ক্লিক করুন এবং ইনস্ট্যান্সে যান নির্বাচন করুন। এটি হিপ ডাম্প থেকে সংশ্লিষ্ট দৃষ্টান্ত নির্বাচন করে, আপনাকে তার নিজস্ব ইনস্ট্যান্স ডেটা দেখায়।

আপনার হিপ ডাম্পে, নিম্নলিখিতগুলির যে কোনও একটির কারণে মেমরি লিকের সন্ধান করুন:

  • Activity , Context , View , Drawable , এবং অন্যান্য অবজেক্টের দীর্ঘকালের রেফারেন্স যা Activity বা Context কন্টেনারে একটি রেফারেন্স ধারণ করতে পারে।
  • নন-স্ট্যাটিক অভ্যন্তরীণ ক্লাস, যেমন একটি Runnable , যা একটি Activity উদাহরণ ধারণ করতে পারে।
  • ক্যাশে যা প্রয়োজনের চেয়ে বেশি সময় অবজেক্ট ধরে রাখে।

একটি HPROF ফাইল হিসাবে একটি হিপ ডাম্প সংরক্ষণ করুন

আপনি একটি হিপ ডাম্প ক্যাপচার করার পরে, প্রোফাইলার চলমান থাকাকালীনই মেমরি প্রোফাইলারে ডেটা দেখা যায়। আপনি যখন প্রোফাইলিং সেশন থেকে প্রস্থান করেন, আপনি হিপ ডাম্প হারাবেন। সুতরাং, আপনি যদি পরে পর্যালোচনার জন্য এটি সংরক্ষণ করতে চান, একটি HPROF ফাইলে হিপ ডাম্প রপ্তানি করুন৷ অ্যান্ড্রয়েড স্টুডিও 3.1 এবং তার নিচের, ফাইলে রপ্তানি ক্যাপচার বোতামটি টাইমলাইনের নীচে টুলবারের বাম দিকে রয়েছে; অ্যান্ড্রয়েড স্টুডিও 3.2 এবং উচ্চতর, সেশন ফলকে প্রতিটি হিপ ডাম্প এন্ট্রির ডানদিকে একটি এক্সপোর্ট হিপ ডাম্প বোতাম রয়েছে৷ এক্সপোর্ট অ্যাজ ডায়ালগে প্রদর্শিত .hprof ফাইল-নাম এক্সটেনশনের সাথে ফাইলটি সংরক্ষণ করুন৷

jhat এর মত একটি ভিন্ন HPROF বিশ্লেষক ব্যবহার করতে, আপনাকে HPROF ফাইলটিকে Android ফরম্যাট থেকে Java SE HPROF ফরম্যাটে রূপান্তর করতে হবে। আপনি android_sdk /platform-tools/ ডিরেক্টরিতে দেওয়া hprof-conv টুল দিয়ে তা করতে পারেন। দুটি আর্গুমেন্ট সহ hprof-conv কমান্ড চালান: আসল HPROF ফাইল এবং রূপান্তরিত HPROF ফাইল লেখার অবস্থান। উদাহরণ স্বরূপ:

hprof-conv heap-original.hprof heap-converted.hprof

একটি হিপ ডাম্প ফাইল আমদানি করুন

একটি HPROF ( .hprof ) ফাইল আমদানি করতে, একটি নতুন প্রোফাইলিং সেশন শুরু করুন ক্লিক করুন৷ সেশন প্যানে, ফাইল থেকে লোড নির্বাচন করুন এবং ফাইল ব্রাউজার থেকে ফাইলটি নির্বাচন করুন।

আপনি ফাইল ব্রাউজার থেকে একটি সম্পাদক উইন্ডোতে টেনে এনে একটি HPROF ফাইল আমদানি করতে পারেন৷

মেমরি প্রোফাইলারে লিক সনাক্তকরণ

মেমরি প্রোফাইলারে একটি হিপ ডাম্প বিশ্লেষণ করার সময়, আপনি প্রোফাইলিং ডেটা ফিল্টার করতে পারেন যা অ্যান্ড্রয়েড স্টুডিও মনে করে আপনার অ্যাপে Activity এবং Fragment ইনস্ট্যান্সের জন্য মেমরি লিক হতে পারে।

ফিল্টারটি যে ধরণের ডেটা দেখায় তার মধ্যে নিম্নলিখিতগুলি অন্তর্ভুক্ত রয়েছে:

  • Activity দৃষ্টান্ত যা ধ্বংস করা হয়েছে কিন্তু এখনও উল্লেখ করা হচ্ছে।
  • Fragment দৃষ্টান্তগুলির একটি বৈধ FragmentManager নেই কিন্তু এখনও উল্লেখ করা হচ্ছে।

নির্দিষ্ট পরিস্থিতিতে, যেমন নিম্নলিখিত, ফিল্টার মিথ্যা ইতিবাচক ফল দিতে পারে:

  • একটি Fragment তৈরি করা হয়েছে কিন্তু এখনও ব্যবহার করা হয়নি।
  • একটি Fragment ক্যাশে করা হচ্ছে কিন্তু একটি FragmentTransaction অংশ হিসাবে নয়।

এই বৈশিষ্ট্যটি ব্যবহার করতে, প্রথমে একটি হিপ ডাম্প ক্যাপচার করুন বা Android স্টুডিওতে একটি হিপ ডাম্প ফাইল আমদানি করুন ৷ মেমরি লিক হতে পারে এমন টুকরো এবং ক্রিয়াকলাপগুলি প্রদর্শন করতে, চিত্র 7-এ দেখানো হিসাবে, মেমরি প্রোফাইলারের হিপ ডাম্প প্যানে অ্যাক্টিভিটি/ফ্র্যাগমেন্ট লিকস চেকবক্স নির্বাচন করুন।

প্রোফাইলার: মেমরি লিক সনাক্তকরণ

চিত্র 7. মেমরি ফাঁসের জন্য একটি হিপ ডাম্প ফিল্টার করা।

আপনার মেমরি প্রোফাইলিং জন্য কৌশল

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

আপনি নিম্নলিখিত উপায়ে একটি মেমরি লিক ট্রিগার করতে পারেন:

  • ডিভাইসটিকে পোর্ট্রেট থেকে ল্যান্ডস্কেপে ঘোরান এবং বিভিন্ন অ্যাক্টিভিটি অবস্থায় থাকা অবস্থায় একাধিকবার আবার ফিরে যান। ডিভাইসটি ঘোরানোর ফলে প্রায়শই একটি অ্যাপ্লিকেশান একটি Activity , Context বা View অবজেক্ট লিক করতে পারে কারণ সিস্টেমটি Activity পুনরায় তৈরি করে এবং যদি আপনার অ্যাপটি অন্য কোথাও সেই বস্তুগুলির একটির রেফারেন্স ধারণ করে, তবে সিস্টেম এটি আবর্জনা সংগ্রহ করতে পারে না।
  • বিভিন্ন অ্যাক্টিভিটি অবস্থায় থাকাকালীন আপনার অ্যাপ এবং অন্য অ্যাপের মধ্যে স্যুইচ করুন (হোম স্ক্রিনে নেভিগেট করুন, তারপরে আপনার অ্যাপে ফিরে আসুন)।

টিপ: আপনি মাঙ্কিরানার টেস্ট ফ্রেমওয়ার্ক ব্যবহার করেও উপরের ধাপগুলি সম্পাদন করতে পারেন।