Sunday, February 19, 2017

স্ট্রিং পুল কী (What is String Pool)

জাভা ভার্চুয়াল মেশিনে মেমোরি মডেল (Memory Model) দুই ভাবে বিভক্ত। এরা হলো হিপ এবং থ্রেড স্ট্যাক। জাভা অ্যাপ্লিকেশনে যত ধরনের অবজেক্ট তৈরি হয়, সেগুলোর সব থাকে হিপে। স্ট্রিং পুল (String Pool) জাভা হিপের একটি বিশেষ এলাকা।

জাভাতে স্ট্রিং একটি বহুল ব্যবহৃত ক্লাস। যেহেতু এটি ইমিউটেবল, তাই স্ট্রিং নিয়ে কাজ করার সময় হিপে অনেক নতুন নতুন স্ট্রিং অবজেক্ট তৈরি হয়। এছাড়াও স্ট্রিং অবজেক্ট নিজেও অনেক বেশি মেমোরি নিয়ে থাকে। একটি স্ট্রিং অবজেক্ট কত বাইট মেমোরি নেয় তা হিসাব করে বের করে ফেলা যায়।

একটি স্ট্রিং অবজেক্টে থাকে একটি ক্যারেক্টার অ্যারে এবং একটি ইন্টিজার হ্যাশ (Hash)। ইন্টিজারের জন্য দরকার হয় 4 বাইট এবং ক্যারেক্টারের জন্য দরকার হয় 2 বাইট। সুতরাং একটি স্ট্রিংয়ে যদি n সংখ্যক ক্যারেক্টার থাকে তাহলে,


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

উদ্ধৃতি চিহ্ন দিয়ে অর্থাৎ স্ট্রিং লিটারেল ব্যবহার করে নতুন একটি স্ট্রিং তৈরি করা সময়, একইরকম স্ট্রিং অবজেক্ট যদি আগে থেকেই স্ট্রিং পুলে থেকে থাকে, তাহলে নতুন করে আর তৈরি না করে আগের অবজেক্টটির রেফারেন্স দেওয়া হয়।

String string1 = "abcd";

String string2 = "abcd";

উপরের দুটি লাইনের জন্য যদিও দুটি অবেজেক্ট থাকার কথা, কিন্তু আসলে জাভা হিপে একটি স্ট্রিং অবজেক্টই থাকবে, দুটি তৈরি হবে না।

তবে new অপারেটর ও কনস্ট্রাক্টর ব্যবহার করে স্ট্রিং তৈরি করলে তা স্ট্রিং পুলে যায় না।

String str = new String("str");

উপরের লাইনটি আসলে দুটি স্ট্রিং তৈরি করে। এটিকে এভাবে লেখা যায়,

String usingLiteral = "str"; // its in the pool

String newString = new String(usingLiteral); // not in the pool

সুতরাং দেখা যাচ্ছে যে এভাবে স্ট্রিং তৈরি করলে সবসময় অতিরিক্তি স্ট্রিং তৈরি হচ্ছে যা মোটেও কাম্য নয়। সুতরাং স্ট্রিং তৈরি করার জন্য সবসময় লিটারেল ব্যবহার করুন।

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

এছাড়াও, আমরা জানি যে স্ট্রিংয়ের হ্যাশকোড (Hashcode) খুব বেশি ব্যবহার করা হয়। যেমন হ্যাশম্যাপ (HashMap)। স্ট্রিং ইমিউটেবল হওয়ায় এটা নিশ্চিত যে, সবসময় হ্যাশকোড একই হবে, সুতরাং আমরা প্রতিবার হ্যাশকোড হিসাব না করে নির্দ্বিধায় ক্যাশিং (Caching) করতে পারি।

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

তাছাড়া স্ট্রিং ইমিউটেবল হওয়ায় এটি স্বাভাবিকভাবে থ্রেড সেইফ (Thread safe) এবং স্বাধীনভাবে যেকোনো থ্রেড অ্যাকসেস করে পারে। এতে করে আমাদেরকে কষ্ট করে এর থ্রেড সেইফটি নিয়ে চিন্তা করতে হয় না।