.NET এ আবর্জনা সংগ্রহ বোঝা


170

নীচের কোডটি বিবেচনা করুন:

public class Class1
{
    public static int c;
    ~Class1()
    {
        c++;
    }
}

public class Class2
{
    public static void Main()
    {
        {
            var c1=new Class1();
            //c1=null; // If this line is not commented out, at the Console.WriteLine call, it prints 1.
        }
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Console.WriteLine(Class1.c); // prints 0
        Console.Read();
    }
}

এখন, যদিও মূল পদ্ধতির ভেরিয়েবল সি 1 এর সুযোগের বাইরে রয়েছে এবং যখন GC.Collect()ডাকা হয় তখন অন্য কোনও বস্তুর দ্বারা আরও রেফারেন্স করা হয় না , কেন এটি সেখানে চূড়ান্ত হয় না?


8
জিসি যখন সুযোগের বাইরে থাকে তখন অবিলম্বে বিনামূল্যে দমন করে না। এটি যখন প্রয়োজন মনে করে এটি এটি করে। : আপনি এখানে জিসি সম্পর্কে সবকিছু পড়তে পারেন msdn.microsoft.com/en-US/library/vstudio/0xy59wtx.aspx
user1908061

@ ব্যবহারকারী1908061 (পিএসএস্ট। আপনার লিঙ্কটি নষ্ট হয়েছে))
ড্রাগগমক

উত্তর:


352

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

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

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

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

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

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

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

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

আপনি এখন যা দেখেছিলেন এবং কেন আপনি প্রশ্ন জিজ্ঞাসা করেছেন তা এটিও এখন ব্যাখ্যা করে। এটি "0" মুদ্রণ করে কারণ জিসি.কোলেক্ট কলটি রেফারেন্স সংগ্রহ করতে পারে না। টেবিলটি বলে যে ভেরিয়েবল অতীত ব্যবহারে রয়েছে আপ পদ্ধতি শেষে সব পথ, GC.Collect () কল। ডিবাগারটি সংযুক্ত করে এবং ডিবাগ বিল্ডটি চালিয়ে বলার জন্য জোর করে ।

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


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


1
আমার প্রশ্নটিও দেখুন যা হান্স আমার পক্ষে সুন্দর উত্তর দিয়েছে। stackoverflow.com/questions/15561025/…
ডেভ নায়

1
: @HansPassant আমি শুধু এই ভয়ঙ্কর ব্যাখ্যা, যা এখানে আমার প্রশ্ন অংশ উত্তর পাওয়া যায় নি stackoverflow.com/questions/30529379/... জিসি এবং থ্রেড সিঙ্ক্রোনাইজেশন সম্পর্কে। আমার কাছে এখনও একটি প্রশ্ন রয়েছে: আমি ভাবছি যে জিসি আসলে কোনও রেজিস্টারে ব্যবহৃত (সাসপেনড থাকা অবস্থায় স্মৃতিতে সঞ্চিত) ব্যবহার করা হয় এমন ঠিকানাগুলি বা যোগাযোগগুলি আপডেট করে কিনা বা কেবল সেগুলি এড়িয়ে চলে? থ্রেড স্থগিতের পরে পুনরায় নিবন্ধগুলি আপডেট করার প্রক্রিয়া (পুনরায় শুরু করার আগে) আমার কাছে ওএস দ্বারা অবরুদ্ধ এমন গুরুতর সুরক্ষা থ্রেডের মতো মনে হয়।
অ্যাটলাস্ট

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

1
@ হ্যান্সপাসান্ট, আপনি এখানে বর্ণিত সিএলআর আবর্জনা সংগ্রাহকের কিছু স্পষ্ট বিবরণের জন্য রেফারেন্স যুক্ত করলে আমি প্রশংসা করব?
denfromufa

দেখে মনে হচ্ছে কনফিগারেশন অনুসারে একটি গুরুত্বপূর্ণ বিষয় হ'ল "অপটিমাইজ কোড" ( <Optimize>true</Optimize>ইন .csproj) সক্ষম করা আছে। এটি "রিলিজ" কনফিগারেশনে ডিফল্ট। তবে যদি কেউ কাস্টম কনফিগারেশন ব্যবহার করে তবে সেটিংসটি গুরুত্বপূর্ণ এটি জেনে রাখা প্রাসঙ্গিক।
জিরো 3

34

[চূড়ান্তকরণ প্রক্রিয়াটির অভ্যন্তরীণে কেবল আরও যোগ করতে চেয়েছিল]

সুতরাং, আপনি একটি বস্তু তৈরি করেন এবং যখন বস্তুটি সংগ্রহ করা হয়, তখন অবজেক্টের Finalizeপদ্ধতিটি কল করা উচিত। তবে এই অতি সাধারণ অনুমানের চেয়ে চূড়ান্তকরণের আরও অনেক কিছুই রয়েছে।

সংক্ষিপ্ত ধারণা ::

  1. যে Finalizeপদ্ধতিগুলি প্রয়োগ করে না, সেখানে মেমরিটি তত্ক্ষণাত পুনরুদ্ধার করা হয়, অবশ্যই যদি না সেগুলি
    প্রয়োগের কোডের মাধ্যমে আর পৌঁছানো যায় না

  2. বাস্তবায়ন অবজেক্টস Finalizeপদ্ধতি, ধারণা / বাস্তবায়নের Application Roots, Finalization Queue, Freacheable Queueআগে তারা উদ্ধারকৃত যাবে আসে।

  3. অ্যাপ্লিকেশন কোড দ্বারা যদি তা অ্যাক্সেসযোগ্য না হয় তবে কোনও বস্তুকে আবর্জনা হিসাবে বিবেচনা করা হবে

অনুমান করুন: শ্রেণি / অবজেক্টস এ, বি, ডি, জি, এইচ Finalizeপদ্ধতি এবং সি, ই, এফ, আই, জে বাস্তবায়ন করে না Finalizeপদ্ধতি প্রয়োগ করে ।

যখন কোনও অ্যাপ্লিকেশন একটি নতুন অবজেক্ট তৈরি করে, নতুন অপারেটরটি গাদা থেকে মেমরি বরাদ্দ করে। যদি অবজেক্টের ধরণে কোনও Finalizeপদ্ধতি থাকে তবে অবজেক্টের একটি পয়েন্টার চূড়ান্তকরণের সারিতে স্থাপন করা হয়

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

Finalize, এবং কিছু না। যখন সি, ই, এফ, আই এবং জে বস্তু তৈরি করা হয়েছিল, তখন। নেট ফ্রেমওয়ার্কটি সনাক্ত করে যে এই বিষয়গুলির জন্য Finalizeপদ্ধতি এবং পয়েন্টারগুলি চূড়ান্তকরণের সারিতে যুক্ত করা হয় ।

এখানে চিত্র বর্ণনা লিখুন

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

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

Finalize পদ্ধতিটি কল ।

সংগ্রহের পরে (1 ম সংগ্রহ), পরিচালিত হিপ নীচের চিত্রের মতো কিছু দেখাচ্ছে। নীচে বর্ণিত ব্যাখ্যা:
১।) অবজেক্টস বি, জি এবং এইচ দ্বারা দখল করা মেমরিটি অবিলম্বে পুনরুদ্ধার করা হয়েছে কারণ এই বস্তুগুলির একটি চূড়ান্ত পদ্ধতি নেই যা কল করার প্রয়োজন ছিল

২) তবে, E, I, এবং J বিষয়বস্তু দ্বারা দখল করা স্মৃতি পুনরুদ্ধার করা যায়নি কারণ তাদের Finalizeপদ্ধতিটি এখনও কল করা হয়নি। ফাইনালাইজ পদ্ধতিটি কল করা ফ্রিচিয়েবল কাতারে সম্পন্ন হয়

৩) এ, সি, ডি, এফ এখনও উপরের হলুদ বাক্স থেকে তীরগুলির মাধ্যমে চিত্রিত অ্যাপ্লিকেশন কোড দ্বারা পৌঁছনযোগ্য, সুতরাং সেগুলি কোনও ক্ষেত্রেই সংগ্রহ করা হবে না

এখানে চিত্র বর্ণনা লিখুন

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

পরের বার যখন আবর্জনা সংগ্রহকারীকে আহ্বান করা হবে (২ য় সংগ্রহ), এটি দেখতে পাবে যে চূড়ান্তীকৃত বস্তুগুলি সত্যই আবর্জনা, যেহেতু অ্যাপ্লিকেশনটির শিকড় এটি নির্দেশ করে না এবং ফ্রেইচ্যাবল সারিতে আর এটি চিহ্নিত করা হয় না ( এটিও EMPTY ), সুতরাং বস্তুগুলির জন্য মেমরি (E, I, J) কেবল হ্যাপ থেকে পুনরুদ্ধার করা হয়েছে below নীচের চিত্রটি দেখুন এবং একে একে উপরের চিত্রের সাথে তুলনা করুন

এখানে চিত্র বর্ণনা লিখুন

এখানে বোঝার জন্য গুরুত্বপূর্ণ বিষয়টি হ'ল চূড়ান্তকরণের প্রয়োজন এমন বস্তুর দ্বারা ব্যবহৃত স্মৃতি পুনরায় দাবি করতে দুটি জিসি প্রয়োজন । বাস্তবে, এই জিনিসগুলি কোনও পুরানো প্রজন্মের দিকে প্রচারিত হতে পারে বলে দুটিরও বেশি সংগ্রহের ক্যাব এমনকি প্রয়োজনীয়

উল্লেখ্য :: freachable কিউ একটি রুট বিশ্বব্যাপী এবং স্ট্যাটিক ভেরিয়েবল ঠিক শিকড় আছে বলে মনে করা হয়। অতএব, যদি কোনও বস্তু অবলম্বনযোগ্য কাতারে থাকে তবে অবজেক্টটি পৌঁছনীয় এবং এটি আবর্জনা নয়।

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.