দ্রষ্টব্য: আমি ধরে নিতে চলেছি যে আপনার মেশিনটির একটি মেমরি ম্যাপিং ইউনিট (এমএমইউ) রয়েছে। এখানে একটি লিনাক্স সংস্করণ (linClinux) রয়েছে যার কোনও এমএমইউ প্রয়োজন হয় না এবং এই উত্তরটি সেখানে প্রয়োগ হয় না।
এমএমইউ কী? এটি প্রসেসরের এবং / অথবা মেমরি নিয়ামকের হার্ডওয়্যার অংশ। ভাগ করা লাইব্রেরি লিঙ্কিং বোঝার জন্য আপনাকে কোনও এমএমইউ কীভাবে কাজ করে তা ঠিক বুঝতে হবে না, কেবলমাত্র এমএমইউ সেখানে লজিকাল মেমরি অ্যাড্রেস (প্রোগ্রামগুলির দ্বারা ব্যবহৃত) এবং শারীরিক মধ্যে পার্থক্য রাখতে দেয়মেমরি ঠিকানা (মেমোরি বাসে আসলে উপস্থিত রয়েছে) present মেমরিটি পৃষ্ঠাগুলিতে বিভক্ত হয়, লিনাক্সে সাধারণত 4K আকারের হয়। 4 কে পৃষ্ঠাগুলির সাথে লজিকাল ঠিকানা 0-4095 পৃষ্ঠা 0, যৌক্তিক ঠিকানা 4096–8191 পৃষ্ঠা 1, ইত্যাদি। এমএমইউ সেগুলি র্যামের দৈহিক পৃষ্ঠাগুলিতে ম্যাপ করে এবং প্রতিটি যৌক্তিক পৃষ্ঠা সাধারণত 0 বা 1 দৈহিক পৃষ্ঠায় ম্যাপ করা যায়। একটি প্রদত্ত শারীরিক পৃষ্ঠা একাধিক লজিকাল পৃষ্ঠাগুলির সাথে অনুরূপ হতে পারে (এইভাবে মেমরি ভাগ করা হয়: একাধিক লজিকাল পৃষ্ঠাগুলি একই শারীরিক পৃষ্ঠার সাথে মিলে যায়)। ওএস নির্বিশেষে এটি প্রযোজ্য নোট করুন; এটি হার্ডওয়ারের বিবরণ।
প্রক্রিয়া স্যুইচ-এ, কার্নেলটি এমএমইউ পৃষ্ঠা ম্যাপিংগুলিকে পরিবর্তন করে, যাতে প্রতিটি প্রক্রিয়াটির নিজস্ব স্থান থাকে। প্রক্রিয়াতে 4096 ঠিকানাটি 10001 প্রক্রিয়াতে 4096 ঠিকানা থেকে সম্পূর্ণ (এবং সাধারণত হয়) সম্পূর্ণ আলাদা হতে পারে।
খুব সুন্দর আপনি যখনই কোনও ঠিকানা দেখেন এটি একটি যৌক্তিক ঠিকানা। ব্যবহারকারীর স্পেস প্রোগ্রামগুলি কদাচিৎ শারীরিক ঠিকানাগুলির সাথে লেনদেন করে।
এখন, পাঠাগারগুলিও তৈরি করার একাধিক উপায় রয়েছে। ধরা যাক একটি প্রোগ্রাম foo()
লাইব্রেরিতে ফাংশনটি কল করে । সিপিইউ প্রতীক সম্পর্কে কিছুই জানে না, বা ফাংশনটি সত্যই কল করে — এটি কেবলমাত্র কীভাবে একটি যৌক্তিক ঠিকানায় ঝাঁপিয়ে পড়তে হয়, এবং সেখানে যা কিছু কোড খুঁজে পায় তা কার্যকর করে। এটি করতে পারে এমন বেশ কয়েকটি উপায় রয়েছে (এবং একটি লাইব্রেরি যখন নিজস্ব গ্লোবাল ডেটা ইত্যাদি ব্যবহার করে তখন একই জিনিস প্রয়োগ করা হয়):
- এটিতে কল করার জন্য এটি কিছু যুক্তিসঙ্গত ঠিকানা হার্ড-কোড করতে পারে। এর জন্য প্রয়োজন লাইব্রেরিটি সর্বদা একই লজিক্যাল ঠিকানায় লোড করা উচিত। দুটি লাইব্রেরিতে যদি একই ঠিকানা প্রয়োজন হয় তবে গতিশীল সংযোগ ব্যর্থ হয় এবং আপনি প্রোগ্রামটি চালু করতে পারবেন না। গ্রন্থাগারগুলিতে অন্যান্য গ্রন্থাগারগুলির প্রয়োজন হতে পারে, সুতরাং এটির জন্য মূলত সিস্টেমের প্রতিটি লাইব্রেরিটির অনন্য লজিকাল ঠিকানা থাকা প্রয়োজন। এটি খুব দ্রুত, যদিও এটি কাজ করে। (এইভাবে a.out কীভাবে কাজ করেছিল এবং প্রিলিংকিংয়ের মতো ধরণের সেট আপ করা হয়েছে)।
- এটি একটি নকল লজিক্যাল ঠিকানা হার্ড-কোড করতে পারে এবং লাইব্রেরিটি লোড করার সময় ডায়নামিক লিঙ্কারটিকে যথাযথভাবে সম্পাদনা করতে বলে। লাইব্রেরিগুলি লোড করার সময় এটির জন্য বেশ খানিকটা সময় ব্যয় হয় তবে এর পরে এটি খুব দ্রুত।
- এটি ইন্ডিয়ারেশনের একটি স্তর যুক্ত করতে পারে: লাইব্রেরিতে লোড হওয়া লজিক্যাল ঠিকানাকে ধরে রাখতে একটি সিপিইউ রেজিস্টার ব্যবহার করুন এবং তারপরে সেই রেজিস্টার থেকে অফসেট হিসাবে সমস্ত কিছু অ্যাক্সেস করুন। এটি প্রতিটি অ্যাক্সেসের জন্য পারফরম্যান্স ব্যয় চাপায়।
খুব সুন্দর কেউ আর # 1 ব্যবহার করে না, কমপক্ষে সাধারণ-উদ্দেশ্য সিস্টেমে নয়। যে অনন্য লজিকাল ঠিকানা তালিকা রাখা 32-বিট সিস্টেমে অসম্ভব (এখানে ঘুরতে যাওয়ার যথেষ্ট পরিমাণ নেই) এবং -৪-বিট সিস্টেমে প্রশাসনিক দুঃস্বপ্ন। প্রি-লিঙ্কিং সাজানোর পদ্ধতি এটি প্রতি সিস্টেমের ভিত্তিতে করে।
# 2 বা # 3 ব্যবহৃত হয় কিনা তা নির্ভর করে লাইব্রেরিটি জিসিসির -fPIC
(অবস্থানের স্বাধীন কোড) বিকল্পের সাথে নির্মিত হয়েছিল কিনা । # 2 ছাড়া, # 3 সাথে রয়েছে। সাধারণত, লাইব্রেরিগুলি দিয়ে নির্মিত হয় -fPIC
, তাই # 3 যা হয়।
আরও বিশদের জন্য, আলরিচ ড্রিপারের ভাগ করে নেওয়া গ্রন্থাগারগুলি কীভাবে লিখবেন (পিডিএফ) দেখুন ।
সুতরাং, অবশেষে, আপনার প্রশ্নের উত্তর দেওয়া যেতে পারে:
- লাইব্রেরিটি যদি এটি দিয়ে নির্মিত হয়
-fPIC
(এটি প্রায় অবশ্যই হওয়া উচিত) তবে পৃষ্ঠাগুলির সিংহভাগই প্রতিটি লোড হওয়া প্রক্রিয়ার জন্য হুবহু একই। আপনার প্রক্রিয়াগুলি a
এবং b
বিভিন্ন লজিকাল ঠিকানায় গ্রন্থাগারটি ভালভাবে লোড করতে পারে তবে সেগুলি একই শারীরিক পৃষ্ঠাগুলিতে নির্দেশ করবে: মেমরিটি ভাগ করা হবে। আরও, র্যামে থাকা ডেটা ডিস্কের সাথে যা ঠিক আছে তার সাথে মেলে, তাই কেবলমাত্র পৃষ্ঠা ফল্ট হ্যান্ডলারের প্রয়োজন হলে এটি লোড করা যায়।
- যদি লাইব্রেরিটি তৈরি না করে নির্মিত হয়
-fPIC
, তবে দেখা যাচ্ছে যে লাইব্রেরির বেশিরভাগ পৃষ্ঠার জন্য লিঙ্ক সম্পাদনা প্রয়োজন হবে এবং এটি আলাদা হবে। অতএব, তাদের অবশ্যই পৃথক শারীরিক পৃষ্ঠাগুলি হতে হবে (যেহেতু এগুলিতে বিভিন্ন ডেটা রয়েছে)। তার মানে তারা ভাগ করা হয়নি। পৃষ্ঠাগুলি ডিস্কে যা আছে তার সাথে মেলে না, তাই পুরো লাইব্রেরিটি লোড হলে আমি অবাক হব না। এটি অবশ্যই পরবর্তীকালে ডিস্কে সরে যেতে পারে (সোয়াপফাইলে)।
আপনার সাথে এই পরীক্ষা করতে পারেন pmap
টুল, অথবা সরাসরি বিভিন্ন ফাইল চেক করে /proc
। উদাহরণস্বরূপ, এখানে pmap -x
দুটি পৃথক নতুন-স্প্যানগুলির একটি (আংশিক) আউটপুট bc
। নোট করুন যে পিএমএপ দ্বারা প্রদর্শিত ঠিকানাগুলি সাধারণ, লজিকাল ঠিকানা হিসাবে:
pmap -x 14739
Address Kbytes RSS Dirty Mode Mapping
00007f81803ac000 244 176 0 r-x-- libreadline.so.6.2
00007f81803e9000 2048 0 0 ----- libreadline.so.6.2
00007f81805e9000 8 8 8 r---- libreadline.so.6.2
00007f81805eb000 24 24 24 rw--- libreadline.so.6.2
pmap -x 17739
Address Kbytes RSS Dirty Mode Mapping
00007f784dc77000 244 176 0 r-x-- libreadline.so.6.2
00007f784dcb4000 2048 0 0 ----- libreadline.so.6.2
00007f784deb4000 8 8 8 r---- libreadline.so.6.2
00007f784deb6000 24 24 24 rw--- libreadline.so.6.2
আপনি দেখতে পারেন যে লাইব্রেরিটি একাধিক অংশে লোড হয়েছে এবং pmap -x
প্রতিটি পৃথকভাবে আপনাকে বিশদ দেয়। আপনি লক্ষ্য করবেন যে দুটি প্রক্রিয়ার মধ্যে যৌক্তিক ঠিকানাগুলি পৃথক; আপনি যুক্তিসঙ্গতভাবে তাদের একই হওয়ার আশা করতেন (যেহেতু এটি একই প্রোগ্রাম চলমান থাকে, এবং কম্পিউটারগুলি সাধারণত এর মতো অনুমানযোগ্য) তবে এড্রেস স্পেস লেআউট র্যান্ডমাইজেশন নামে একটি সুরক্ষা বৈশিষ্ট্য রয়েছে যা তাদের উদ্দেশ্যমূলকভাবে এলোমেলো করে তোলে।
আপনি আকার (কেবিটিস) এবং আবাসিক আকারের (আরএসএস) পার্থক্য থেকে দেখতে পারেন যে পুরো লাইব্রেরি অংশটি লোড করা হয়নি। অবশেষে, আপনি দেখতে পাচ্ছেন যে বৃহত্তর ম্যাপিংয়ের জন্য, নোংরা 0, যার অর্থ এটি ডিস্কের সাথে ঠিক মিলে যায়।
আপনি এর সাথে পুনরায় রান করতে পারেন pmap -XX
এবং এটি আপনাকে দেখাবে - আপনি যে কার্নেল সংস্করণটি চালাচ্ছেন তার উপর নির্ভর করে -XX আউটপুট কার্নেল সংস্করণ অনুসারে পরিবর্তিত হয় — প্রথম ম্যাপিংয়ের Shared_Clean
176 রয়েছে যা সঠিকভাবে মেলে RSS
। Shared
স্মৃতি মানে শারীরিক পৃষ্ঠাগুলি একাধিক প্রক্রিয়ার মধ্যে ভাগ করা হয় এবং যেহেতু এটি আরএসএসের সাথে মিলে যায়, তার অর্থ স্মৃতিতে থাকা সমস্ত লাইব্রেরি ভাগ করা হয় (ভাগ করা বনাম প্রাইভেটের আরও ব্যাখ্যার জন্য নীচে দেখুন দেখুন):
pmap -XX 17739
Address Perm Offset Device Inode Size Rss Pss Shared_Clean Shared_Dirty Private_Clean Private_Dirty Referenced Anonymous AnonHugePages Swap KernelPageSize MMUPageSize Locked VmFlagsMapping
7f784dc77000 r-xp 00000000 fd:00 1837043 244 176 19 176 0 0 0 176 0 0 0 4 4 0 rd ex mr mw me sd libreadline.so.6.2
7f784dcb4000 ---p 0003d000 fd:00 1837043 2048 0 0 0 0 0 0 0 0 0 0 4 4 0 mr mw me sd libreadline.so.6.2
7f784deb4000 r--p 0003d000 fd:00 1837043 8 8 8 0 0 0 8 8 8 0 0 4 4 0 rd mr mw me ac sd libreadline.so.6.2
7f784deb6000 rw-p 0003f000 fd:00 1837043 24 24 24 0 0 0 24 24 24 0 0 4 4 0 rd wr mr mw me ac sd libreadline.so.6.2
আরো দেখুন
-fPIC
কিছুক্ষণ আগে ব্যবহারটি পুরোপুরি বদলে গেছে)?