স্মৃতিশক্তি হ্রাস পেয়েছে কিনা আমাকে জিজ্ঞাসা না করে লিনাক্স কি আমার প্রক্রিয়াগুলি মেরে ফেলা শুরু করবেন?


66

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

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

স্মৃতিশক্তি শেষ হয়ে যাওয়ার পরে লিনাক্স আমার প্রোগ্রামগুলি মেরে ফেলতে পারে? এবং এটি কি সম্ভব যে পরে যে বিভাগগুলিক ত্রুটিগুলি আমি পেয়েছিলাম তা আমার প্রোগ্রামগুলি চালানোর জন্য উপলব্ধ মেমরির অভাবের কারণে হয়েছিল (আমার কোডটিতে বাগের পরিবর্তে)?


2
আপনি যখন মেমরি বরাদ্দ করেন, তখন কী আপনার কাছে স্মৃতিটি সফলভাবে বরাদ্দ করা হয়েছিল তা পরীক্ষা করার জন্য কোনও বিবৃতি আছে? এটি আপনার কোডটিতে বাগ আছে কিনা বা এটি সিস্টেমে স্মৃতির অভাবের কারণে হয়েছে কিনা তা একটি সূত্র সরবরাহ করা উচিত।
আনটনাট

উত্তর:


72

এটা হতে পারে.

লিনাক্সে আপনি মুখোমুখি হতে পারেন এমন দুটি ভিন্ন মেমরির শর্ত রয়েছে। আপনার মুখোমুখি যা sysctl vm.overcommit_memory( /proc/sys/vm/overcommit_memory) এর মান উপর নির্ভর করে

ভূমিকা:
কার্নেলটি 'মেমরি ওভারকমিট' নামে পরিচিত যা সম্পাদন করতে পারে। এটি তখন হয় যখন কার্নেল সিস্টেমের মধ্যে উপস্থিত উপস্থিতির চেয়ে বেশি মেমরির বরাদ্দ দেয়। এটি এই প্রত্যাশায় করা হয় যে প্রোগ্রামগুলি তাদের বরাদ্দকৃত সমস্ত মেমরি ব্যবহার করবে না কারণ এটি একটি সাধারণ ঘটনা।

overcommit_memory = 2

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

সেগফল্টের ক্ষেত্রে আপনার আউটপুটে একটি লাইন পাওয়া উচিত dmesg:

[1962.987529] myapp[3303]: segfault at 0 ip 00400559 sp 5bc7b1b0 error 6 in myapp[400000+1000]

এর at 0মানে হল যে অ্যাপ্লিকেশনটি একটি অবিশ্রান্ত পয়েন্টার অ্যাক্সেস করার চেষ্টা করেছে, যা মেমরি বরাদ্দ কল ব্যর্থ হতে পারে (তবে এটি একমাত্র উপায় নয়)।

overcommit_memory = 0 এবং 1

কখন overcommit_memoryসেট করা হয় 0বা যখন 1, ওভারকমিট সক্ষম করা থাকে এবং প্রোগ্রামগুলিকে সত্যিকারের চেয়ে বেশি মেমরি বরাদ্দ করার অনুমতি দেওয়া হয়।

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

প্রক্রিয়াটি মারা যাওয়ার পরে, এটি ব্যবহার করা মেমরিটি মুক্ত হয়ে যায়, এবং যে প্রোগ্রামটি কেবলমাত্র স্মৃতি-বহির্ভূত অবস্থার কারণ হয়ে গেছে এখন এটির প্রয়োজনীয় স্মৃতি রয়েছে।

যাইহোক, এমনকি এই মোডে, প্রোগ্রামগুলি এখনও বরাদ্দের অনুরোধ অস্বীকার করা যেতে পারে। যখন overcommit_memoryহয় 0, কার্নেল যখন এটি বরাদ্দ অনুরোধ আত্মত্যাগী শুরু করা উচিত এ সেরা অনুমান নিতে চেষ্টা করে। যখন এটি সেট করা থাকে 1, আমি নিশ্চিত নই যে এটি কখন একটি অনুরোধ অস্বীকার করবে তা নির্ধারণ করতে এটি কোন দৃ what়সংকল্পটি ব্যবহার করে তবে এটি খুব বড় অনুরোধকে অস্বীকার করতে পারে।

OOM-Killer এর আউটপুট দেখে dmesgএবং কোনও বার্তা খুঁজে বার করে যেমন দেখতে পান:

[11686.043641] Out of memory: Kill process 2603 (flasherav) score 761 or sacrifice child
[11686.043647] Killed process 2603 (flasherav) total-vm:1498536kB, anon-rss:721784kB, file-rss:4228kB

সুতরাং, মনে হয় উভয় পরিস্থিতি আমার সাথে ঘটেছিল।
নিউট্রনস্টার

@ জোশুয়া আমি কেবল উত্তরটি আপডেট করেছি। আমি উল্লেখ করতে ভুলে গেছি যে overcommit_memory0 বা 2 এ সেট করা আছে আপনি এখনও বরাদ্দ ব্যর্থতা পেতে পারেন
প্যাট্রিক

আমি মনে করি পোস্টে ওওএম কিলারকে টেমিংয়ের লিঙ্ক সম্পাদনা করা সার্থক হতে পারে।
0xC0000022L

@ 0xC0000022L ধন্যবাদ, এটি একটি ভাল নিবন্ধ (যদিও তারিখের বাইরে কিছুটা হলেও)। আমি ওওম হত্যাকারীকে নিয়ন্ত্রণের বিষয়ে কিছু রাখতে চাইনি যেহেতু এটি প্রশ্নের অংশ নয় (এবং এটি কোনও সংক্ষিপ্ত বিষয় নয়), এবং আমাদের এখানে আরও অনেক প্রশ্ন রয়েছে ঠিক এটি সম্পর্কে।
প্যাট্রিক

1
@ মিকসার্ভ আমি এটি বলি না যে ওওএম ঘাতকের আচরণ নিয়ন্ত্রণের সাথে এটির কোনও সম্পর্ক নেই। প্রশ্ন ছিল লিনাক্স তার প্রোগ্রামগুলি মেরে ফেলবে কিনা। লিনাক্সকে কীভাবে এটি করা থেকে আটকাতে হবে তার জন্য এটি অবশ্যই লিনাক্সই করা দরকার। এবং যদি overcommit_memory=2, OOM হত্যাকারী এমনকি সক্ষম না হয়, তাই এটি নিয়ন্ত্রণ করা অপ্রাসঙ্গিক। যাইহোক একবার যদি আমরা এটি স্থাপন করি যে এটি ওওএম হত্যাকারী, এটি অন্য একটি বিষয় হয়ে ওঠে যেখানে এখানে আরও অনেক প্রশ্ন ও উত্তর দ্বারা আবৃত।
প্যাট্রিক

16

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

যদিও overcommit_memory=লিনাক্স হলে OOM kills ব্যবস্থাপনা কনফিগার অধিকাংশ সাধারণ উপায়, এটি মত প্রক্রিয়া প্রতি বিন্যাসযোগ্য হল:

echo [-+][n] >/proc/$pid/oom_adj

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

আপনি প্রতিটি প্রক্রিয়া অনুযায়ী ওওএম হ্যান্ডলারের বর্তমান সেটিংস পরীক্ষা করতে পারেন:

cat /proc/$pid/oom_score 

অন্যথায় আপনি আত্মহত্যা করতে পারেন:

sysctl vm.panic_on_oom=1
sysctl kernel.panic=X

এটি মেমোরির বাইরে থাকা অবস্থায় কম্পিউটারটিকে রিবুট করতে সেট করবে। আপনি উপরেরটিকে Xসেকেন্ডের সংখ্যায় সেট করেছেন যে আপনি কম্পিউটারটি পুনরায় বুট করার আগে কার্নেল আতঙ্কের পরে থামতে চান। বুনো যাও।

এবং যদি কোনও কারণে, আপনি সিদ্ধান্ত নিতে চান যে আপনি এটি পছন্দ করেন তবে এটি অবিচল করুন:

echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
echo "kernel.panic=X" >> /etc/sysctl.conf

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

3
@ জোশুয়া - আমি অত্যন্ত গুরুত্বের সাথে সন্দেহ করি যে কেউ এটি পছন্দ করতে পারে - এটি রোবোটিকের অসীমভের আইনকেও অস্বীকার করে। অন্যদিকে, যেমনটি আমি উল্লেখ করেছি, আপনি অন্যান্য প্রক্রিয়া অনুযায়ী ওওএমটিও কনফিগার করতে পারেন। যার অর্থ হল আপনি ব্যক্তিগতভাবে নিজের প্রক্রিয়া অনুযায়ী নিজের সংজ্ঞায়িত নিয়মসেটের উপর ভিত্তি করে ট্রিজেস করতে পারেন। এই জাতীয় জিনিসটি মনে হচ্ছে এটি ভাগ করে নেওয়া ক্লাস্টারের দৃশ্যে বিশেষত কার্যকর।
মাইক্রোজার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.