জাভা অবজেক্টগুলি স্থির করে দেওয়া কি আর কিছু করতে পারে?


112

আমি কিছু পুরানো বই ব্রাউজ করছিলাম এবং পিটার হ্যাজারের "প্রাকটিক্যাল জাভা" এর একটি অনুলিপি পেয়েছি। কর্মক্ষমতা বিভাগে, nullযখন আর প্রয়োজন হবে না তখন অবজেক্ট রেফারেন্স সেট করার জন্য একটি প্রস্তাবনা রয়েছে is

জাভাতে, nullকর্মক্ষমতা বা আবর্জনা সংগ্রহের দক্ষতার উন্নতির জন্য অবজেক্টের রেফারেন্স সেট করা কি না ? যদি তা হয় তবে কোন ক্ষেত্রে এটি একটি সমস্যা? ধারক ক্লাস? অবজেক্ট কম্পোজিশন? নামবিহীন অভ্যন্তর শ্রেণি?

আমি কোড এ দেখতে প্রায়শই প্রায়ই। এটি এখন অপ্রচলিত প্রোগ্রামিং পরামর্শ বা এটি এখনও দরকারী?


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

12
@ জেসন, প্রোফাইল এটি? এটি ধরে নিয়েছে যে এর উত্তর দেওয়ার জন্য আমি যথেষ্ট পরিমাণে কেস সেট করব। এবং আমি যে কেসগুলিকে ভিসি GMC এবং পারফরম্যান্সের সমস্যার মুখোশ দেওয়ার জন্য যথেষ্ট অনুকূল করে ফেলেছি সেগুলির একটি সেট আমি বেছে নিই না। এই কারণেই আমি এখানে এটি জিজ্ঞাসা করছি। এই সমস্যা যেখানে ক্ষেত্রে একটি ধারণা পেতে।
সাল

উত্তর:


73

আপনি যখন রেফারেন্সটি বাতিল করার কথা ভাবছিলেন তখন এটি কিছুটা নির্ভর করে।

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

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

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

{
  BigObject obj = ...
  doSomethingWith(obj);
  obj = null;             <-- explicitly set to null
  doSomethingElse();
}

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


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

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

25

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

কার্যকর জাভা 2 য় সংস্করণ, আইটেম 6 দেখুন: অপ্রচলিত অবজেক্ট রেফারেন্সগুলি বাদ দিন।


এটি কি কোনও ভাষা ইস্যু বা ভিএম বাস্তবায়ন সমস্যা?
পাবলো সান্তা ক্রুজ

4
এটি একটি "শব্দার্থক" বিষয়। মূলত, আপনি কোনও অ্যারের আগে থেকে স্থির করে রেখেছেন বলে ভিএম তা দেখে। এটি আপনার ধারকটির "যৌক্তিক" আকার সম্পর্কে কিছুই জানে না। বলুন আপনার 16 মাপের অ্যারে দ্বারা ব্যাকড 10 মাপের অ্যারেলিস্ট রয়েছে। ভিএম জানতে পারে না যে আইটেমগুলি ১০.১৫ ব্যবহার করা হয় না; যদি এই স্লটগুলির বিষয়বস্তু থাকে তবে সেগুলি মুক্ত হবে না।
ক্রিস জেস্টার-ইয়ং

ধারক ক্লাসের বাইরের কি হবে? অবজেক্ট কম্পোজিশনে যেখানে আভ্যন্তরীণ অবজেক্টটি বাইরের অবজেক্টের দ্বারা ডি-বরাদ্দ নয়।
সাল

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

2
একই আইটেম you এ
এসিভি

10

তাত্ক্ষণিক ক্ষেত্র, অ্যারের উপাদান

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

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

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

স্কোপড ভেরিয়েবল:

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

{
  BigObject obj = ...
  doSomethingWith(obj);
  obj = null;          //   <-- explicitly set to null
  doSomethingElse();
}

হয়ে

{
  {  
     BigObject obj = ...
     doSomethingWith(obj);
  }    //         <-- obj goes out of scope
  doSomethingElse();
}

দীর্ঘ, ফ্ল্যাট স্কোপগুলি কোডের সুগমতার জন্য সাধারণত খারাপ। কেবল সেই উদ্দেশ্যে জিনিসগুলি ভেঙে ফেলার জন্য ব্যক্তিগত পদ্ধতিগুলি প্রবর্তন করা খুব শোনা যায় না।


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

5

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

প্রতিদিনের প্রোগ্রামিংয়ের ক্ষেত্রে তবে ক্রিস জেস্টার-ইয়ং-এর মতো বিশেষ কিছু বাদে এই নিয়ম হওয়া উচিত নয়।


1

প্রথমত, এর অর্থ এমন কোনও কিছু নয় যে আপনি কোনও বস্তু সেট করছেন null। আমি এটি নীচে ব্যাখ্যা:

List list1 = new ArrayList();
List list2 = list1;

উপরের কোড বিভাগে আমরা অবজেক্ট রেফারেন্স ভেরিয়েবলের নাম তৈরি করছি list1 এর ArrayListমেমরি মধ্যে সংরক্ষিত হয় অবজেক্ট। সুতরাং list1যে অবজেক্ট উল্লেখ করা হয় এবং এটি একটি ভেরিয়েবল ছাড়া কিছুই। এবং কোডের দ্বিতীয় লাইনে আমরা রেফারেন্সটি অনুলিপি list1করছি list2। সুতরাং এখন আপনার প্রশ্নে ফিরে যদি আমি করি:

list1 = null;

এর মানে list1 আর কোনও বস্তুর উল্লেখ নেই যা স্মৃতিতে সঞ্চিত রয়েছে তাই list2উল্লেখ করার মতো কিছুই থাকবে না। সুতরাং আপনি যদি আকারটি পরীক্ষা করেন list2:

list2.size(); //it gives you 0

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

আমি আশা করি এটি ধারণাটি পরিষ্কার হয়ে গেছে।


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