কেন বড় অবজেক্টের গাদা এবং কেন আমরা যত্ন নিই?


105

আমি জেনারেশন এবং লার্জ অবজেক্ট হিপ সম্পর্কে পড়েছি। তবে আমি এখনও বুঝতে ব্যর্থ হয়েছি যে বড় অবজেক্টের হিপ থাকার তাৎপর্য (বা সুবিধা) কী?

কী ভুল হতে পারে (পারফরম্যান্স বা মেমোরির ক্ষেত্রে) যদি সিএলআর স্রেফ জেনারেশন 2 (জেন 0 এবং জেন 1 এর বৃহত্তর বস্তুগুলি হ্যান্ডেল করার পক্ষে ছোট) বিবেচনা করে থাকে তবে বড় বস্তু সংরক্ষণের জন্য?


6
এটি আমাকে নেট ডিজাইনারদের জন্য দুটি প্রশ্ন দেয়: ১. আউটআফমিউরিএক্সসেপশন নিক্ষেপের আগে এলওএইচ ডিফ্র্যাগ কেন বলা হয় না? ২. কেন এলওএইচ অবজেক্টের একসাথে থাকার জন্য সখ্যতা নেই (বৃহত্তর স্তূপের
জ্যাকব ব্রুয়ার

উত্তর:


195

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

কমপ্যাক্টিং কেবল বাইটগুলি অনুলিপি করেই করা হয়। এটি অবশ্য সময় নেয়। অবজেক্টটি যত বড় হবে, সম্ভবত এটির অনুলিপি করার ব্যয় সিপিইউ ক্যাশে ব্যবহারের উন্নতির তুলনায় অনেক বেশি।

সুতরাং তারা বিরতি-সমান পয়েন্ট নির্ধারণ করতে একগুচ্ছ মানদণ্ড চালিয়েছে। এবং 85,000 বাইটে কাট অফ পয়েন্ট হিসাবে পৌঁছেছে যেখানে অনুলিপি করা আর পারফের উন্নতি করে না। ডাবল অ্যারেগুলির জন্য একটি বিশেষ ব্যতিক্রম ছাড়া, অ্যারেতে 1000 এরও বেশি উপাদান থাকে তখন এগুলি 'বড়' হিসাবে বিবেচিত হয়। এটি 32-বিট কোডের জন্য আরেকটি অপ্টিমাইজেশন, বৃহত অবজেক্ট হিপ বরাদ্দকারীটির বিশেষ সম্পত্তি রয়েছে যা এটি 8 এ সারিবদ্ধ ঠিকানায় মেমরি বরাদ্দ করে, নিয়মিত প্রজন্মের বরাদ্দকারীদের বিপরীতে যা কেবলমাত্র 4 টি সারিবদ্ধ করে বরাদ্দ করে That এই প্রান্তিককরণটি দ্বিগুণ জন্য বড় চুক্তি , ভুল-সংযুক্ত ডাবল পড়া বা লেখা খুব ব্যয়বহুল। অদ্ভুতভাবে স্পার্স মাইক্রোসফ্ট তথ্য কখনও দীর্ঘ অ্যারের উল্লেখ করে না, তার সাথে কী হবে তা নিশ্চিত নয়।

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

একটি সমস্যা যা অন্যথায় কেবল একটি 64-বিট অপারেটিং সিস্টেমে কোড চালিয়ে সম্পূর্ণ অদৃশ্য হয়ে যায়। একটি 64-বিট প্রক্রিয়াটিতে 8 টেরাবাইট ভার্চুয়াল মেমরি অ্যাড্রেস স্পেস উপলব্ধ রয়েছে, 32-বিট প্রক্রিয়াটির চেয়ে 3 মাপের বাড়ির অর্ডার রয়েছে। আপনি কেবল গর্ত থেকে চালাতে পারবেন না।

দীর্ঘ গল্প সংক্ষেপে, এলওএইচ কোড রানকে আরও দক্ষ করে তোলে। উপলব্ধ ভার্চুয়াল মেমরি ঠিকানা স্পেস কম দক্ষ ব্যবহার করে।


আপডেট, .NET 4.5.1 এখন এলওএইচ , জিসিএসটিটিংগুলিকে কমপ্যাক্ট করা সমর্থন করে ar লার্জওজেক্টহিপকম্পশনমোড সম্পত্তি। দয়া করে পরিণতি সাবধান।


3
@ હંস প্যাস্যান্ট, আপনি কি দয়া করে x64 সিস্টেম সম্পর্কে স্পষ্ট করে বলতে পারছেন, আপনি বলতে চাইছেন যে এই সমস্যাটি পুরোপুরি অদৃশ্য হয়ে গেছে?
জনি_ডি

এলওএইচের কিছু বাস্তবায়ন বিশদটি বোঝায় তবে কিছু আমাকে ধাঁধা দেয়। উদাহরণস্বরূপ, আমি বুঝতে পারি যে যদি অনেক বড় অবজেক্ট তৈরি করা এবং পরিত্যাজ্য করা হয় তবে জেন 0 সংগ্রহের টুকরা মেশিনের তুলনায় জেন 2 সংগ্রহের ক্ষেত্রে সাধারণভাবে মুছে ফেলা বাঞ্ছনীয় হতে পারে তবে যদি কেউ 22,000 স্ট্রিংয়ের একটি অ্যারে তৈরি করে এবং ছেড়ে দেয় তবে বাহিরের কোনও রেফারেন্স উপস্থিত নেই, অ্যারেতে কোনও রেফারেন্স বিদ্যমান কিনা তা বিবেচনা না করে জেন0 এবং জেন 1 সংগ্রহের সমস্ত 22,000 স্ট্রিংকে "লাইভ" হিসাবে ট্যাগ করার কী সুবিধা রয়েছে?
supercat

6
অবশ্যই বিভাজন সমস্যা x64 এ ঠিক একই। আপনার সার্ভার প্রক্রিয়াটি শুরু হওয়ার আগে এটি চালিয়ে যেতে আরও কয়েক দিন সময় লাগবে
লোথার

1
হুম, না, কখনও কখনও 3 মাপের ক্রমকে অবমূল্যায়ন করবেন না। 4 টেরাবাইট হ্যাপ সংগ্রহ করতে আবর্জনা নিতে কত সময় লাগে এটি এমন কিছু যা আপনি এটির কাছাকাছি যাওয়ার আগে আবিষ্কার করা এড়াতে পারবেন না।
হান্স প্যাস্যান্ট

2
@ হ্যান্সপাস্যান্ট আপনি কী দয়া করে এই বিবৃতিতে বিশদভাবে বলতে পারেন: "4 টেরাবাইটের গাদা জঞ্জাল সংগ্রহ করতে কতক্ষণ সময় লাগে এটি এমন কিছুর কাছাকাছি যাওয়ার আগে আপনি এটি আবিষ্কার করতে এড়াতে পারবেন না।"
অপেক্ষাকৃত_রান্দম

9

যদি বস্তুর আকারটি কিছু পিনযুক্ত মানের (85000 বাইটগুলিতে .NET 1) এর চেয়ে বেশি হয়, তবে সিএলআর এটিকে বড় অবজেক্ট হ্যাপে রাখে। এটি অনুকূলিত করে:

  1. অবজেক্ট বরাদ্দ (ছোট বস্তু বড় বস্তুর সাথে মিশ্রিত হয় না)
  2. আবর্জনা সংগ্রহ (এলওএইচ কেবলমাত্র পুরো জিসিতে সংগ্রহ করা)
  3. মেমরি ডিফ্র্যাগমেন্টেশন (এলওএইচ কখনই কমপ্যাক্ট হয় না )

9

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

বিটিডাব্লু, এই পোস্ট অনুসারে , LOH সাধারণত মেমরি খণ্ডের সমস্যা তৈরি করে না।


1
পরিচালিত অবজেক্টগুলিতে প্রচুর পরিমাণে ডেটা লোড করা সাধারণত LOH কমপ্যাক্ট করতে 8 এমএস ব্যয়কে বামন করে। বেশিরভাগ বড় ডেটা অ্যাপ্লিকেশনগুলিতে অনুশীলনে, LOH ব্যয়টি অ্যাপ্লিকেশনটির বাকী পারফরম্যান্সের পাশে নগণ্য।
শিব

3

অধ্যক্ষটি হ'ল এটি অসম্ভব (এবং সম্ভবত বেশ খারাপ নকশা) যে কোনও প্রক্রিয়া প্রচুর স্বল্পজীবী বড় বস্তু তৈরি করবে তাই সিএলআর বৃহত অবজেক্টগুলিকে একটি পৃথক স্তূপে বরাদ্দ করে যার উপর এটি জিসিকে নিয়মিত গাদা করার জন্য আলাদা সময়সূচিতে চালায়। http://msdn.microsoft.com/en-us/magazine/cc534993.aspx


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

আমি মনে করি এটি কেবলমাত্র খারাপ ডিজাইন কারণ জিসি এটি ভালভাবে পরিচালনা করে না।
কোডসইনচাওস

@ কোডইন চাওস স্পষ্টতই, কিছু উন্নতি আসছে। নেট 4.5
খ্রিস্টান.কে

1
@ কোডইনচাউস: এমনকি একটি স্বল্প-কালীন এলওএইচ বস্তু থেকে স্মৃতি পুনরায় দাবি করার আগে জিন 2 সংগ্রহের আগে পর্যন্ত সিস্টেমটির জন্য অপেক্ষা করা বুদ্ধিমান হয়ে উঠতে পারে, তবে এলওএইচ অবজেক্টগুলি (এবং তারা যে কোনও বস্তু ধারণ করে) তা ঘোষণা করার জন্য আমি কোনও কার্যকারিতা সুবিধা দেখতে পাচ্ছি না রেফারেন্সগুলি) জেন0 এবং জেন 1 সংগ্রহের সময় নিঃশর্ত লাইভ। এমন কিছু অনুমানের দ্বারা সম্ভব হয়েছে এমন কিছু অপ্টিমাইজেশন রয়েছে কি?
সুপারক্যাট

@ সুপের্যাট আমি মাইলস ম্যাকডনেল উল্লিখিত লিঙ্কটির দিকে তাকালাম। আমার বোধগম্যতা হল: 1. এলওএইচ সংগ্রহ জেনার 2 জিসিতে ঘটে in 2. এলওএইচ সংগ্রহের মধ্যে সংযোগ নেই (নিবন্ধটি লেখা হয়েছিল)। পরিবর্তে, এটি মৃত বস্তুগুলিকে পুনরায় ব্যবহারযোগ্য হিসাবে চিহ্নিত করবে এবং এই গর্তগুলি যথেষ্ট বড় হলে ভবিষ্যতে LOH বরাদ্দ দেবে। পয়েন্ট 1 এর কারণে, জেন 2-তে অনেকগুলি বস্তু থাকলে জেনার 2 জিসি ধীরে ধীরে হবে বলে বিবেচনা করে আমি মনে করি এই ক্ষেত্রে যতটা সম্ভব এলওএইচ ব্যবহার করা এড়ানো ভাল better
রবি ফ্যান

0

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

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