স্মৃতি খণ্ডন কী?


203

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

  • স্মৃতি খণ্ডন কী?
  • আমার অ্যাপ্লিকেশনের জন্য মেমরি বিভাজন একটি সমস্যা কিনা তা আমি কীভাবে বলতে পারি? কোন ধরণের প্রোগ্রামটি সবচেয়ে বেশি ক্ষতিগ্রস্থ হতে পারে?
  • মেমরি খণ্ডিত করার জন্য সাধারণ সাধারণ উপায়গুলি কী কী?

এছাড়াও:

  • আমি শুনেছি গতিশীল বরাদ্দ ব্যবহার করে মেমরি খণ্ডন বাড়াতে পারে। এটা কি সত্য? সি ++ এর প্রসঙ্গে আমি সমস্ত স্ট্যান্ডার্ড পাত্রে বুঝতে পারি (স্ট্যান্ড :: স্ট্রিং, স্টাড :: ভেক্টর ইত্যাদি) গতিশীল মেমরি বরাদ্দ ব্যবহার করে। এগুলি যদি কোনও প্রোগ্রাম জুড়ে ব্যবহৃত হয় (বিশেষত স্টাড :: স্ট্রিং), মেমরি খণ্ডিত হওয়ার কি সমস্যা হওয়ার সম্ভাবনা বেশি?
  • কোনও এসটিএল-ভারী অ্যাপ্লিকেশনটিতে কীভাবে মেমরি খণ্ডন করা যায়?

1
প্রচুর দুর্দান্ত উত্তর, সবাইকে ধন্যবাদ!
অ্যাশলেস ব্রেন

4
ইতিমধ্যে প্রচুর দুর্দান্ত উত্তর রয়েছে, তবে এখানে একটি আসল অ্যাপ্লিকেশন (ফায়ারফক্স) থেকে কিছু ছবি দেওয়া আছে যেখানে মেমরির খণ্ডন
২০০7 /

2
@ মারিয়াসজেডমিনাস লিঙ্কটি আর কাজ করে না এই কারণেই লিঙ্কটি সহ একটি সংক্ষিপ্ত সংক্ষিপ্ত বিবরণ প্রদান বা লিঙ্কটি সহ সংক্ষিপ্তসার দিয়ে প্রশ্নের উত্তর দেওয়া গুরুত্বপূর্ণ
কাট্টা

অবশ্যই তবে এটি অর্ধ দশকেরও বেশি সময়
পেরিয়ে গেছে

3
নীচে মারিয়াস পোস্ট লিঙ্কগুলির জন্য একটি আপডেট অবস্থান: pavlovdotnet.wordpress.com/2007/11/10/
মেমরি-

উত্তর:


312

কল্পনা করুন যে আপনার কাছে "বড়" (32 বাইট) ফ্রি মেমরির প্রসার রয়েছে:

----------------------------------
|                                |
----------------------------------

এখন, এর কিছু বরাদ্দ করুন (5 টি বরাদ্দ):

----------------------------------
|aaaabbccccccddeeee              |
----------------------------------

এখন, প্রথম চারটি বরাদ্দ বিনামূল্যে করুন তবে পঞ্চম নয়:

----------------------------------
|              eeee              |
----------------------------------

এখন, 16 বাইট বরাদ্দ করার চেষ্টা করুন। ওফস, আমি পারছি না, যদিও এটি প্রায় দ্বিগুণ বিনামূল্যে free

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

----------------------------------
|ffffffffffffffeeeeff            |
----------------------------------

যদিও ভার্চুয়াল মেমরিটি (অনেক বড় হওয়া) এর মতো দেখতে পারা যায়:

------------------------------------------------------...
|              eeeeffffffffffffffff                   
------------------------------------------------------...

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

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

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

স্ট্যান্ডার্ড লাইব্রেরিগুলি মেমরির বরাদ্দকারী যে কোনও কিছুর চেয়ে খারাপ নয় এবং স্ট্যান্ডার্ড পাত্রে Allocসমস্তগুলির একটি টেম্পলেট প্যারামিটার রয়েছে যা আপনি যদি তাদের প্রয়োজন বরাদ্দ কৌশলটি সঠিকভাবে জরিমানা-সুর করতে ব্যবহার করতে পারেন absolutely


1
সুতরাং প্রতিটি চরিত্র একটি বাইট? যা আপনার "বৃহত বিস্তৃতি" == 32 বাইট তৈরি করবে (আমি অনুমান করছি - গণনা করা হয়নি) :) দুর্দান্ত উদাহরণ, তবে শেষ লাইনের আগে ইউনিটগুলি উল্লেখ করা সহায়ক হবে। :)
জলফ

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

একটি "উত্তর" নির্বাচন করা বেশ কঠিন ছিল - এখানে প্রচুর দুর্দান্ত উত্তর রয়েছে এবং আমি আগ্রহী যে কাউকে সেগুলি পড়তে উত্সাহিত করেছি। তবুও, আমি মনে করি আপনি এখানে সমস্ত গুরুত্বপূর্ণ পয়েন্ট coveredেকে রেখেছেন।
অ্যাশলেব্রাইন

1
"স্ট্যান্ডার্ড লাইব্রেরি মেমরির বরাদ্দকারী যে কোনও কিছু থেকে খারাপ নয়"। এটি যদি সত্য হয় তবে দুর্দান্ত হবে তবে স্ট্রিং এবং ভেক্টরের মতো স্ট্যান্ডার্ড সি ++ টেম্পলেটগুলির বাস্তবায়নের ক্ষেত্রে তারা পুনরায় আকার দেওয়ার সময় কিছু অত্যন্ত অনাকাঙ্ক্ষিত আচরণ করতে পারে। উদাহরণস্বরূপ ভিজ্যুয়াল স্টুডিওর পুরানো সংস্করণগুলিতে std :: স্ট্রিং মূলত রিলোক 1.5 * কারেন্ট_সাইজ (নিকটতম 8 বাইটে) দ্বারা আকার পরিবর্তন করে। সুতরাং আপনি যদি কোনও স্ট্রিংয়ের সাথে সংযুক্ত রাখেন তবে খুব সহজেই বিশেষত এম্বেড থাকা সিস্টেমে আপনি গাদাটি সহজেই অ্যাহিলিট করতে পারেন। লুকানো রিলোকগুলি এড়ানোর জন্য আপনি যে পরিমাণ জায়গার প্রত্যাশা করছেন তা হ'ল সেরা প্রতিরক্ষা।
লোককা

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

73

স্মৃতি খণ্ডন কী?

মেমরি খণ্ডিত হ'ল যখন আপনার বেশিরভাগ স্মৃতি প্রচুর পরিমাণে অ-সঙ্গতিপূর্ণ ব্লক বা অংশগুলিতে বরাদ্দ করা হয় - আপনার মোট মেমরির বেশিরভাগ শতাংশ অবিকৃত রেখে দেওয়া হয় তবে বেশিরভাগ সাধারণ পরিস্থিতিতে unus এর ফলে মেমরি ব্যতিক্রম বা বরাদ্দ ত্রুটিগুলি (যেমন malloc নাল ফেরায়) এর ফলস্বরূপ।

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

এখন, কল্পনা করুন যে প্রাচীরটি আপনার (গাদা) মেমরি এবং ছবিগুলি বস্তুগুলি .. এটি মেমরির খণ্ডন ...

আমার অ্যাপ্লিকেশনের জন্য মেমরি বিভাজন একটি সমস্যা কিনা তা আমি কীভাবে বলতে পারি? কোন ধরণের প্রোগ্রামটি সবচেয়ে বেশি ক্ষতিগ্রস্থ হতে পারে?

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

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

মেমরি খণ্ডিত করার জন্য সাধারণ সাধারণ উপায়গুলি কী কী?

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


10
+1 টি। আমি সবেমাত্র আমার প্রস্তাবিত উত্তরটি মুছে ফেলেছি কারণ আপনার "দেয়ালের চিত্রগুলি" রূপকটি সত্যই, সত্যই একটি ভাল, পরিষ্কার।
ctacke

ছবিগুলি বিভিন্ন আকারের হতে হবে এই বিষয়টিতে আপনি যদি জোর দিয়ে থাকেন তবে আমি এটি আরও চাই। অন্যথায়, কোনও খণ্ডন ঘটবে না।
Björn Pollex

1
মজার বিষয় হল, মূল মেমরির ডেটাবেসগুলি আজকাল কিছুটা ব্যবহারিক হয়ে উঠছে (সত্যিই অনেক বেশি স্মৃতি উপলব্ধ রয়েছে)। এই প্রসঙ্গে এটি লক্ষণীয় যে এইচডিডিগুলির হিসাবে, র‌্যাম থেকে অবিচ্ছিন্ন লাইনগুলি পড়া খুব সহজেই ডেটা খণ্ডিত হয় than
Björn Pollex

1
দেওয়ালের ছবিগুলির সাথে দুর্দান্ত ভিজ্যুয়াল উপমা, তবে প্রধান স্মৃতিটি দ্বিমাত্রিক নয়! তবুও, সুন্দর উত্তর যদিও, ধন্যবাদ।
অ্যাশলেব্রাইন

24

মেমরি বিভাজন হ'ল ডিস্ক বিভাজন হিসাবে একই ধারণা: এটি স্থান নষ্ট হওয়া বোঝায় কারণ ব্যবহৃত অঞ্চলগুলি একসাথে যথেষ্ট পরিমাণে প্যাক না করে।

ধরুন, একটি সাধারণ খেলনা উদাহরণের জন্য আপনার মেমরির দশটি বাইট রয়েছে:

 |   |   |   |   |   |   |   |   |   |   |
   0   1   2   3   4   5   6   7   8   9

এবার আসুন তিন, তিনটি বাইট ব্লক, নাম দিন এ, বি এবং সি:

 | A | A | A | B | B | B | C | C | C |   |
   0   1   2   3   4   5   6   7   8   9

এখন বি ব্লক বিলোপ করুন:

 | A | A | A |   |   |   | C | C | C |   |
   0   1   2   3   4   5   6   7   8   9

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

আপনি কীভাবে জানবেন যে এটি একটি সমস্যা? ভাল, সবচেয়ে বড় লক্ষণটি হ'ল আপনি যে মেমরিটি ব্যবহার করছেন তা তার চেয়ে আপনার প্রোগ্রামটির ভার্চুয়াল মেমরির আকারটি যথেষ্ট বড়। বাস্তব-জগতের উদাহরণে, আপনার কাছে মেমরির দশটি বেশি বাইট থাকবে, সুতরাং ডি কেবলমাত্র 9 বাইট শুরু করে বরাদ্দ পেয়েছে এবং 3-5 বাইট অব্যবহৃত থাকবে যদি না আপনি পরে তিন বাট দীর্ঘ বা আরও কিছু বরাদ্দ করেন।

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

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

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

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


14
  • স্মৃতি খণ্ডন কী?

মেমরি বিভাজন হ'ল মেমোরিটি তাত্ত্বিকভাবে উপলব্ধ থাকলেও অপ্রয়োজনীয় হয়ে ওঠার সমস্যা। দুটি প্রকার বিভাজন রয়েছে: অভ্যন্তরীণ খণ্ডগুলি মেমরি যা বরাদ্দ করা হয় তবে ব্যবহার করা যায় না (উদাহরণস্বরূপ যখন মেমরিটি 8 বাইট খণ্ডে বরাদ্দ করা হয় তবে প্রোগ্রামটি বারবার একক যোগাযোগ করে যখন কেবল 4 বাইট প্রয়োজন) needs বাহ্যিক খণ্ডন হ'ল ফ্রি মেমরির সমস্যাটি অনেক ছোট অংশে বিভক্ত হয়ে যায় যাতে পর্যাপ্ত সামগ্রিক ফ্রি মেমরি থাকা সত্ত্বেও বড় বরাদ্দ অনুরোধগুলি পূরণ করা যায় না।

  • আমার অ্যাপ্লিকেশনের জন্য মেমরি বিভাজন একটি সমস্যা কিনা তা আমি কীভাবে বলতে পারি? কোন ধরণের প্রোগ্রামটি সবচেয়ে বেশি ক্ষতিগ্রস্থ হতে পারে?

মেমরি বিভাজন একটি সমস্যা যদি আপনার প্রোগ্রামটি প্রকৃত পেডলড ডেটার প্রয়োজনের তুলনায় অনেক বেশি সিস্টেম মেমরি ব্যবহার করে (এবং আপনি মেমরি ফাঁসকে অস্বীকার করেছেন)।

  • মেমরি খণ্ডিত করার জন্য সাধারণ সাধারণ উপায়গুলি কী কী?

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

  • পল আর উইলসন, মার্ক এস জনস্টোন, মাইকেল নীলি এবং ডেভিড বোলেস। গতিশীল স্টোরেজ বরাদ্দ: একটি সমীক্ষা এবং সমালোচনা পর্যালোচনা। মেমোরি ম্যানেজমেন্ট 1995-এর আন্তর্জাতিক কর্মশালার কার্যক্রমে, স্প্রিঞ্জার ভার্লাগ এলএনসিএস, 1995
  • মার্ক এস জোনস্টোন, পল আর উইলসন। স্মৃতি বিভাজন সমস্যা: সমাধান? এসিএম সাইন-প্ল্যান নোটিসে, খণ্ড 34 নং 3, পৃষ্ঠা 26-36, 1999
  • এমআর গ্যারি, আরএল গ্রাহাম এবং জেডি উলমান। মেমরি বরাদ্দকরণ অ্যালগরিদমের সবচেয়ে খারাপ কেস বিশ্লেষণ। থিওরি অফ কম্পিউটিংয়ের উপর চতুর্থ বার্ষিক এসিএম সিম্পোজিয়াম, 1972

9

আপডেট:
গুগল টিসি মল্লোক: থ্রেড-ক্যাচিং ম্যালোক
এটি পাওয়া গেছে যে দীর্ঘ চলমান প্রক্রিয়াতে খণ্ডগুলি পরিচালনা করতে এটি বেশ ভাল


আমি একটি সার্ভার অ্যাপ্লিকেশন বিকাশ করছি যা এইচপি-ইউএক্স 11.23 / 11.31 ia64 এ মেমরি বিভাজনে সমস্যা ছিল।

দেখে মনে হচ্ছিল। এমন একটি প্রক্রিয়া ছিল যা মেমরির বরাদ্দ এবং অবনমন করে এবং কয়েক দিন ধরে চলে। এবং কোনও মেমরি ফাঁস না থাকলেও মেমরির ব্যবহারের প্রক্রিয়াটি বাড়তে থাকে kept

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

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

আমি জানি যে এইচপি-ইউএক্স-এ মেমরি বিভাজন এড়ানোর অন্যতম উপায় হ'ল স্মল ব্লক অলোকেটর ব্যবহার করা বা ম্যালোকসেক্সটেন ব্যবহার করা। রেডহ্যাট লিনাক্সে ডিফল্ট বরাদ্দকারী বেশ কয়েকটি ছোট ব্লক বরাদ্দ করতে খুব ভাল পরিচালনা করে। উইন্ডোজটিতে রয়েছে Low-fragmentation Heapএবং এটি বিশাল সংখ্যক ছোট বরাদ্দের সমস্যা সমাধান করে।

আমার বোধগম্যতা হল যে কোনও এসটিএল-ভারী অ্যাপ্লিকেশনটিতে আপনার প্রথমে সমস্যাগুলি সনাক্ত করা উচিত। মেমোরি বরাদ্দকারী (লাইবসির মতো) আসলে অনেকগুলি ছোট বরাদ্দের সমস্যা পরিচালনা করে, যা সাধারণত std::string(আমার সার্ভার অ্যাপ্লিকেশনটিতে প্রচুর এসটিএল স্ট্রিং রয়েছে তবে আমি দেখছি info heapযে এগুলি কোনও সমস্যা সৃষ্টি করছে না)। আমার ধারণাটি হ'ল আপনাকে ঘন ঘন বড় বরাদ্দ এড়ানো উচিত। দুর্ভাগ্যক্রমে এমন পরিস্থিতি রয়েছে যখন আপনি সেগুলি এড়াতে পারবেন না এবং আপনার কোডটি পরিবর্তন করতে হবে। আমি আমার ক্ষেত্রে যেমনটি বলি আমি স্যুইচ করার সময় পরিস্থিতির উন্নতি করেছি std::deque। আপনি যদি নিজের স্মৃতির ক্ষুদ্র অংশ চিহ্নিত করেন তবে এটি সম্পর্কে আরও সুনির্দিষ্টভাবে কথা বলা সম্ভব হতে পারে।


6

যখন আপনি বিভিন্ন আকারের অনেকগুলি বস্তু বরাদ্দ করেন এবং নির্মূল করেন তখন মেমরি বিভাজন সবচেয়ে বেশি ঘটে । ধরুন আপনার মেমোরিতে নিম্নলিখিত লেআউট রয়েছে:

obj1 (10kb) | obj2(20kb) | obj3(5kb) | unused space (100kb)

এখন যখন obj2প্রকাশিত হবে তখন আপনার 120kb অব্যবহৃত মেমরি রয়েছে তবে আপনি 120kb এর সম্পূর্ণ ব্লক বরাদ্দ করতে পারবেন না, কারণ স্মৃতিটি খণ্ডিত হয়েছে।

এই প্রভাবটি এড়ানোর সাধারণ কৌশলগুলির মধ্যে রিং বাফার এবং অবজেক্ট পুল অন্তর্ভুক্ত রয়েছে । এসটিএল প্রসঙ্গে, এর মতো পদ্ধতিগুলি std::vector::reserve()সহায়তা করতে পারে।


6

মেমরি বিভাজন সম্পর্কে একটি খুব বিস্তৃত উত্তর এখানে পাওয়া যাবে।

http://library.softwareverify.com/memory-fragmentation-your-worst-nightmare/

এটি 11 বছরের মেমরি বিভাজনের উত্তরগুলির সমাপ্তি যা আমি লোকেরা আমাকে সফ্টওয়্যারভিটি.কম এ মেমরি বিভাজন সম্পর্কে প্রশ্ন জিজ্ঞাসা করে যাচ্ছি


3

স্মৃতি খণ্ডন কী?

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

অপর একটি, অনিবার্য, তবে ভাঙনের কম সমস্যাযুক্ত উত্স হ'ল বেশিরভাগ আর্কিটেকচারে, মেমরি ঠিকানাগুলি অবশ্যই 2, 4, 8 ইত্যাদিতে আবদ্ধ থাকতে হবে by এমনকি যদি আপনার 3 charক্ষেত্র সমেত একটি স্ট্রাক্ট থাকে তবে প্রতিটি ক্ষেত্রটি 4-বাইট সীমানায় আবদ্ধ হওয়ার কারণে আপনার স্ট্রাক্টটির 3 টির পরিবর্তে 12 আকার থাকতে পারে।

আমার অ্যাপ্লিকেশনের জন্য মেমরি বিভাজন একটি সমস্যা কিনা তা আমি কীভাবে বলতে পারি? কোন ধরণের প্রোগ্রামটি সবচেয়ে বেশি ক্ষতিগ্রস্থ হতে পারে?

এর সুস্পষ্ট উত্তর হ'ল আপনি মেমরির ব্যতিক্রমটি পেয়ে গেছেন।

দৃশ্যত সি ++ অ্যাপ্লিকেশনগুলিতে মেমরি বিভাজন সনাক্ত করার জন্য কোনও ভাল পোর্টেবল উপায় নেই। আরও তথ্যের জন্য এই উত্তর দেখুন ।

মেমরি খণ্ডিত করার জন্য সাধারণ সাধারণ উপায়গুলি কী কী?

সি ++-তে এটি কঠিন, যেহেতু আপনি পয়েন্টারগুলিতে সরাসরি মেমরি ঠিকানা ব্যবহার করেন এবং নির্দিষ্ট মেমরির ঠিকানাটি কে উল্লেখ করেছেন তার উপর আপনার কোনও নিয়ন্ত্রণ নেই। সুতরাং বরাদ্দ হওয়া মেমরি ব্লকগুলি (জাভা আবর্জনা সংগ্রহকারী যেভাবে করে) পুনরায় সাজানো কোনও বিকল্প নয়।

একটি কাস্টম বরাদ্দকারী মেমরির একটি বড় অংশে ছোট ছোট বস্তুর বরাদ্দ পরিচালনার মাধ্যমে এবং সেই অংশের মধ্যে ফ্রি স্লটগুলি পুনরায় ব্যবহার করে সহায়তা করতে পারে।


3

এটি ডমিগুলির জন্য একটি অতি-সরল সংস্করণ।

স্মৃতিতে বস্তুগুলি তৈরি হওয়ার সাথে সাথে তারা মেমরির ব্যবহৃত অংশের শেষে যুক্ত হয়।

মেমরির ব্যবহৃত অংশের শেষে না থাকা কোনও বস্তু যদি মুছে ফেলা হয়, যার অর্থ এই অবজেক্টটি 2 অন্যান্য বস্তুর মধ্যে ছিল, এটি একটি "গর্ত" তৈরি করবে।

এটাকেই ফ্র্যাগমেন্টেশন বলা হয়।


2

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

এখন, স্মৃতি যখন খণ্ডিত হয় তখন দুটি জিনিস ঘটতে পারে:

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

1

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

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

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

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


0

কোন ধরণের প্রোগ্রামটি সবচেয়ে বেশি ক্ষতিগ্রস্থ হতে পারে?

স্মৃতি খণ্ডিত হওয়ার সাথে সম্পর্কিত সমস্যার একটি দুর্দান্ত (= ভয়ঙ্কর) উদাহরণ হ'ল স্টারডকের কম্পিউটার গেম "এলিমেন্টাল: ম্যাজিকের যুদ্ধ" এর বিকাশ ও মুক্তি ।

গেমটি 32 বিট / 2 জিবি মেমরির জন্য নির্মিত হয়েছিল এবং সেই 2 গিগাবাইট মেমোরির মধ্যে গেমটি কাজ করতে মেমরি পরিচালনায় প্রচুর অপ্টিমাইজেশন করতে হয়েছিল। ধ্রুব বরাদ্দ এবং ডি-বরাদ্দ, সময় গাদা মেমরি ফ্র্যাগমেন্টেশন উপর থেকে "অপ্টিমাইজেশান" সীসা হিসাবে ঘটেছে এবং প্রণীত খেলা বিপর্যস্ত প্রত্যেক সময়

ইউটিউবে একটি "যুদ্ধের গল্প" সাক্ষাত্কার রয়েছে।

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