জাভার স্ট্রিং ধ্রুবক পুলটি কোথায় থাকে, হিপ বা স্ট্যাক?


103

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


11
স্ট্যাকের মধ্যে কীভাবে একটি পুল সংরক্ষণ করা যায়? আপনি একটি স্ট্যাক ধারণা জানেন?
স্ক্র্যাম মিস্টার

1
হাই স্ক্র্যাম মিস্টার, আমি চেষ্টা করার চেষ্টা করেছি এটি হতে পারে না। ভুল সম্মেলনের জন্য দুঃখিত। জিসি সম্পর্কে এখনই আমি জানতে পেরেছি। তার জন্য ধন্যবাদ
রেঙ্গাসামি রামানুজাম

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

উত্তর:


74

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


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

1
আপনার উত্তরের জন্য আপনাকে ধন্যবাদ। এই আলোচনা নিয়ে আমি অনেক কিছু বুঝতে পেরেছি। আপনাদের ভাল করে জানা ভাল
লাগলো

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


54

এই উত্তর দ্বারা ব্যাখ্যা হিসাবে , স্ট্রিং পুলের সঠিক অবস্থান নির্দিষ্ট করা হয়নি এবং এক জেভিএম বাস্তবায়ন থেকে অন্যটিতে পরিবর্তিত হতে পারে।

এটি আকর্ষণীয়ভাবে লক্ষণীয় যে জাভা 7 অবধি, পুলটি হটস্পট জেভিএম-র স্তূপের পার্ভেন স্পেসে ছিল তবে জাভা since থেকে এটি স্তূপের মূল অংশে স্থানান্তরিত হয়েছে :

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

এবং জাভা 8 হটস্পটে স্থায়ী জেনারেশন সম্পূর্ণভাবে সরানো হয়েছে।


30

স্ট্রিং লিটারেলগুলি স্ট্যাকের মধ্যে সংরক্ষণ করা হয় না। কখনও। আসলে, কোনও বস্তু স্ট্যাকের মধ্যে সংরক্ষণ করা হয় না।

স্ট্রিং লিটারেল (বা আরো সঠিকভাবে, স্ট্রিং যে বস্তু তাদের প্রতিনিধিত্ব) হয় ঐতিহাসিকভাবে এক গাদা মধ্যে সংরক্ষিত হয় "permgen" গাদা বলা হয়। (স্থায়ী প্রজন্মের জন্য পারমজেন সংক্ষিপ্ত))

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

স্পষ্টকরণ # 1 - আমি বলছি না যে পারমজেন GC'ed পায় না। এটি সাধারণত হয় যখন জেভিএম সম্পূর্ণ জিসি চালানোর সিদ্ধান্ত নেয়। আমার পয়েন্ট স্ট্রিং লিটারেল যতদিন পৌঁছানো হবে যে কোডটি ব্যবহার তাদের পৌঁছানো হয়, এবং কোড যতদিন কোডের classloader যোগাযোগ করা যাবে এবং ডিফল্ট classloaders জন্য পৌঁছানো হবে, তার মানে "চিরদিনের জন্য"।

বর্ণমালা # 2 - প্রকৃতপক্ষে, জাভা 7 এবং পরবর্তীকালে স্ট্রিং পুলটি ধরে রাখতে নিয়মিত গাদা ব্যবহার করে। সুতরাং, স্ট্রিং অবজেক্টস যা স্ট্রিং লিটারেল এবং ইন্টার্ন'ড স্ট্রিংগুলিকে প্রতিনিধিত্ব করে সেগুলি নিয়মিত হিপগুলিতে থাকে। (বিশদগুলির জন্য @ অ্যাসিলিয়াসের উত্তর দেখুন))


তবে আমি এখনও স্ট্রিং আক্ষরিক এবং স্ট্রিংয়ের সাহায্যে স্ট্রিংয়ের স্টোরেজের মধ্যে পাতলা রেখা খুঁজে বের করার চেষ্টা করছি new

কোনও "পাতলা রেখা" নেই। এটা সত্যিই খুব সহজ:

  • String স্ট্রিং প্যাটার্নগুলিতে স্ট্রিং লিটারেলগুলিকে প্রতিনিধিত্ব করা / প্রাসঙ্গিক করে
  • StringString::internকল দ্বারা তৈরি করা বস্তুগুলি স্ট্রিং পুলে ধারণ করা হয়।
  • অন্যান্য সমস্ত Stringঅবজেক্ট স্ট্রিং পুলে রাখা হয় না।

তারপরে স্ট্রিং পুলটি "সঞ্চিত" কোথায় রয়েছে তার আলাদা প্রশ্ন রয়েছে। জাভা 7 এর আগে এটি ছিল পার্জেন হিপ। জাভা 7 থেকে এটি প্রধান গাদা।


23

স্ট্রিং পুলিং

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

জাভা of এর সময়ে স্ট্রিং.ইনটার্ন () ব্যবহার করে পুলিং নিয়ন্ত্রণের বাইরে চলে গেলে আউটআফ মেমরিএক্সসেপশন পাওয়ার উচ্চ সম্ভাবনার কারণে অনেক স্ট্যান্ডার্ড দ্বারা নিষিদ্ধ করা হয়েছিল। ওরাকল জাভা 7 স্ট্রিং পুলিংয়ের বাস্তবায়ন যথেষ্ট পরিবর্তন করা হয়েছিল। আপনি http://bugs.sun.com/view_bug.do?bug_id=6962931 এবং http://bugs.sun.com/view_bug.do?bug_id=6962930 এ বিশদ অনুসন্ধান করতে পারেন ।

জাভা 6 এ স্ট্রিং.ইনটার্ন ()

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

জাভা 6 এ জাতীয় স্ট্রিং পুলের সাথে সবচেয়ে বড় সমস্যাটি ছিল এর অবস্থান - পার্মজেন। পার্মজেনের একটি নির্দিষ্ট আকার থাকে এবং রানটাইমগুলিতে প্রসারিত করা যায় না। আপনি এটি -XX: ম্যাক্স্পার্মসাইজ = 96 মি বিকল্প ব্যবহার করে সেট করতে পারেন। আমি যতদূর জানি ডিফল্ট পার্মজেন আকার প্ল্যাটফর্মের উপর নির্ভর করে 32M এবং 96M এর মধ্যে পরিবর্তিত হয়। আপনি এর আকার বাড়াতে পারেন তবে এর আকারটি এখনও স্থির থাকবে। এই জাতীয় সীমাবদ্ধতার জন্য স্ট্রিং.ইনটার্নের খুব সতর্কতার সাথে ব্যবহার প্রয়োজন - আপনি এই পদ্ধতিটি ব্যবহার করে কোনও অনিয়ন্ত্রিত ব্যবহারকারীর ইনপুটটি ভাল না করাই ভাল। এজন্য জাভা of এর সময়ে স্ট্রিং পুলিং বেশিরভাগ ম্যানুয়ালি পরিচালিত মানচিত্রে প্রয়োগ করা হয়েছিল।

জাভা 7 এ স্ট্রিং.ইনটার্ন ()

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

স্ট্রিং পুল মানগুলি আবর্জনা সংগ্রহ করা হয়

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

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

উৎস.


11

অন্যান্য উত্তরগুলির হিসাবে জাভাতে মেমরি দুটি ব্যাখ্যা করা হয়েছে

1. স্ট্যাক: থ্রেড অনুযায়ী একটি স্ট্যাক তৈরি করা হয় এবং এটি স্ট্যাক ফ্রেমগুলি সংরক্ষণ করে যা আবার স্থানীয় ভেরিয়েবলগুলি সঞ্চয় করে এবং যদি কোনও ভেরিয়েবল একটি রেফারেন্স টাইপ হয় তবে সেই পরিবর্তনশীলটি প্রকৃত অবজেক্টের জন্য স্তূপে একটি মেমরি অবস্থানকে বোঝায়।

২. গাদা: সমস্ত ধরণের অবজেক্টগুলি কেবল স্তূপে তৈরি করা হবে।

হিপ মেমরি আবার 3 ভাগে বিভক্ত করা হয়

1. তরুণ প্রজন্ম: দোকান বস্তু যা একটি সংক্ষিপ্ত জীবন আছে, তরুণ প্রজন্মের নিজেই দুটি বিভাগ ভাগে ভাগ করা যায় ইডেন স্পেস এবং সারভাইভার স্পেস

২. পুরানো জেনারেশন: স্টোর অবজেক্টগুলি যা বহু আবর্জনা সংগ্রহের চক্র থেকে বেঁচে গেছে এবং এখনও রেফারেন্স করা হচ্ছে।

৩. স্থায়ী জেনারেশন: প্রোগ্রাম সম্পর্কে মেটাডেটা সঞ্চয় করে যেমন রানটাইম ধ্রুবক পুল।

স্ট্রিং ধ্রুবক পুল হিপ মেমরির স্থায়ী প্রজন্মের অঞ্চলের অন্তর্গত।

আমরা javap -verbose class_nameবাইকোডে আমাদের কোডের জন্য রানটাইম ধ্রুবক পুল দেখতে পারি যা ব্যবহারের মাধ্যমে আমাদের পদ্ধতি রেফারেন্স (# মেথোড্রেফ), ক্লাস অবজেক্টস (# ক্লাস), স্ট্রিং লিটারেল (# স্ট্রিং) দেখায়

রানটাইম-নির্দিষ্ট-পুকুর

আপনি আমার নিবন্ধে এটি সম্পর্কে আরও পড়তে পারেন কীভাবে জেভিএম অভ্যন্তরীণভাবে ওভারলোডিং এবং ওভাররাইডিং পদ্ধতিটি পরিচালনা করে না


কোনও অনুমোদন প্রকাশ করুন এবং পোস্টের মাধ্যমে আপনার সাইটের প্রচারের উপায় হিসাবে সাইটটি ব্যবহার করবেন না। দেখুন আমি কীভাবে ভাল উত্তর লিখব?

9

ইতিমধ্যে এখানে অন্তর্ভুক্ত থাকা দুর্দান্ত উত্তরে আমি এমন কিছু যুক্ত করতে চাই যা আমার দৃষ্টিকোণে অনুপস্থিত - একটি চিত্রণ।

আপনি ইতিমধ্যে জেভিএম বরাদ্দকৃত মেমরিটিকে একটি জাভা প্রোগ্রামে দুটি ভাগে ভাগ করেছেন। এক স্ট্যাকের এবং অন্য এক গাদা । স্ট্যাক প্রয়োগের উদ্দেশ্যে এবং গাদা সঞ্চয়স্থানের উদ্দেশ্যে ব্যবহৃত হয়। সেই হিপ মেমোরিতে, জেভিএম স্ট্রিং লেটারেলের জন্য বিশেষভাবে বোঝানো কিছু মেমরি বরাদ্দ করে। হিপ মেমরির এই অংশটিকে স্ট্রিং কনস্ট্যান্ট পুল বলা হয় ।

সুতরাং উদাহরণস্বরূপ, যদি আপনি নিম্নলিখিত বিষয়গুলি সূচনা করেন:

String s1 = "abc"; 
String s2 = "123";
String obj1 = new String("abc");
String obj2 = new String("def");
String obj3 = new String("456);

স্ট্রিং লিটারেলস s1এবং s2স্ট্রিং ধ্রুবক পুলে যাবে, অবজেক্টস ইজ 1, অজ 2 তাদের সমস্ত, স্ট্যাক থেকে রেফারেন্স করা হবে।

এছাড়াও, দয়া করে নোট করুন যে "abc" গাদা এবং স্ট্রিং ধ্রুবক পুলে প্রদর্শিত হবে। কেন String s1 = "abc"এবং String obj1 = new String("abc")এইভাবে তৈরি করা হবে? এটি কারণ String obj1 = new String("abc")স্পষ্টভাবে একটি স্ট্রিং অবজেক্টের একটি নতুন এবং সাধারণভাবে স্বতন্ত্র উদাহরণ তৈরি করে এবং String s1 = "abc"স্ট্রিং ধ্রুবক পুল থেকে কোনও উপলভ্য উপস্থিত থাকলে পুনরায় ব্যবহার করতে পারে। আরও বিস্তৃত ব্যাখ্যার জন্য: https://stackoverflow.com/a/3298542/2811258

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


প্রদত্ত চিত্রটিতে, "ডিফ" এবং "456" অক্ষরগুলি কোথায় থাকবে। এবং এগুলি কীভাবে উল্লেখ করা হবে?
সত্যেন্দ্র

@ সত্যেন্দ্র আপনার মন্তব্যের জন্য ধন্যবাদ, আমি চিত্রণ এবং উত্তর আপডেট করেছি।
জনি

@ আপনি অন্য স্ট্রিং অবজেক্ট "অ্যাবসি" তৈরি করেন কেন? আক্ষরিক অধিকারটি নির্দেশ করার জন্য এটি রেফারেন্স অবজেক্ট 1 ব্যবহার করা উচিত?

এর কারণ স্ট্রিংজেজ 1 = নতুন স্ট্রিং ("অ্যাবসি") স্পষ্টভাবে একটি স্ট্রিং অবজেক্টের একটি নতুন এবং প্রাসঙ্গিকভাবে স্বতন্ত্র ঘটনা তৈরি করে এবং স্ট্রিং s1 = "abc" স্ট্রিং ধ্রুবক পুলের কোনও উপস্থিতি উপস্থিত থাকলে পুনরায় ব্যবহার করতে পারে। আরও বিস্তৃত ব্যাখ্যার জন্য: stackoverflow.com/a/3298542/2811258
জনি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.