লিনাক্স কি "র‌্যাম রান আউট" করতে পারে?


20

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

এটা কিভাবে সম্ভব? আমি ভেবেছিলাম যে সমস্ত আধুনিক ওএস শারীরিক র‍্যামের যা কিছু ঘটে তার জন্য কেবল ডিস্ক অদলবদল ব্যবহার করে "অসীম র‌্যাম" সরবরাহ করে। এটা কি সঠিক?

কোনও প্রক্রিয়া "কম র‌্যামের কারণে নিহত" হলে কী ঘটতে পারে?


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

@JohnDibling; সুতরাং কোনও কারণেই কি কেউ ফাইল সিস্টেমের জন্য ডিস্কের স্থান বাঁচানো ছাড়া অন্যদের অদলবদলের আকার সীমাবদ্ধ করতে চায়? অন্য কথায়, যদি আমার কাছে 20 জিবি ডিস্ক এবং কেবল 1 জিবি ফাইল থাকে তবে আমার অদলবদলের আকারটি 19 গিগাবাইটে সেট না করার কোনও কারণ আছে কি?

1
জিনিসগুলিকে বড় করে দেখানোর জন্য, আমি বলব অদলবদলের আকার সীমাবদ্ধ করার দুটি কারণ হ'ল 1) ডিস্কের ব্যবহার হ্রাস করতে এবং 2) কর্মক্ষমতা বাড়ানোর জন্য। পরবর্তীগুলি উইন্ডোজের অধীনে / * এনআইএক্সের চেয়ে বেশি সত্য হতে পারে তবে আপনি যদি আবার আপনার ডিস্কে অদলবদল স্থানটি ব্যবহার করেন তবে আপনার কর্মক্ষমতা হ্রাস পাবে। ডিস্ক অ্যাক্সেসটি হয় র‌্যামের চেয়ে ধীর গতিতে বা সিস্টেমের উপর নির্ভর করে র‌্যামের চেয়ে অনেক ধীর।
জন ডিবলিং

9
সোয়াপ র‌্যাম নয়en.wikedia.org/wiki/Random-access_memory আপনার সিস্টেমে র‌্যামের পরিমাণটি আপনার সিস্টেমে - পিরিয়ডের র‌্যামের পরিমাণ। এটি একটি দ্ব্যর্থক বা গতিশীল ভলিউম নয়। এটা একেবারে স্থির। "মেমোরি" আরও অস্পষ্ট ধারণা, তবে র‌্যাম এবং স্টোরেজের অন্যান্য ফর্মগুলির মধ্যে পার্থক্যটি যেমন টেরডন (+1) দেখায়, এটি বেশ তাৎপর্যপূর্ণ। অনেকগুলি অর্ডার দ্বারা ডিস্ক অদলবস্থা র‍্যামের পারফরম্যান্সের বিকল্প হতে পারে না । অদলবদলের উপর অত্যধিক নির্ভর এমন একটি সিস্টেম সেরা অস্থায়ী এবং সাধারণভাবে: আবর্জনা।
স্বর্ণিলোক

1
তাহলে ডিস্ক স্পেস এখন অসীম?
কাজ

উত্তর:


41

কোনও প্রক্রিয়া "কম র‌্যামের কারণে নিহত" হলে কী ঘটতে পারে?

কখনও কখনও বলা হয় যে ডিফল্টরূপে লিনাক্স অ্যাপ্লিকেশন কোড থেকে আরও মেমরির জন্য অনুরোধকে অস্বীকার করে না - যেমন malloc()1 এটি বাস্তবে সত্য নয়; ডিফল্ট একটি তাত্পর্যপূর্ণ ব্যবহার করে

ঠিকানার জায়গার সুস্পষ্ট ওভার কমিটগুলি অস্বীকার করা হয়েছে। একটি সাধারণ সিস্টেমের জন্য ব্যবহৃত হয়। ওভার কমিটকে অদলবদলের ব্যবহার হ্রাস করার অনুমতি দেওয়ার সাথে সাথে এটি মারাত্মকভাবে বন্য বরাদ্দ ব্যর্থ হওয়ার বিষয়টি নিশ্চিত করে।

থেকে [linux_src]/Documentation/vm/overcommit-accounting(সমস্ত উদ্ধৃতি 3.11 টি গাছের)। ঠিক কীভাবে "গুরুতর বন্য বরাদ্দ" হিসাবে গণনা করা হয়েছে তা সুস্পষ্টভাবে তৈরি করা হয়নি, সুতরাং বিশদটি নির্ধারণের জন্য আমাদের উত্সের মধ্য দিয়ে যেতে হবে। আমরা পাদটীকা 2 (নীচে) -এও পরীক্ষামূলক পদ্ধতিটি ব্যবহার করতে পারি এবং চেষ্টা করতে পারি এবং theত্বিকের কিছু প্রতিবিম্বও পাওয়া যায় - তার ভিত্তিতে আমার প্রাথমিক অভিজ্ঞতা অভিজ্ঞতা পর্যবেক্ষণ করে যে আদর্শ পরিস্থিতিতে (== সিস্টেমটি নিষ্ক্রিয়), যদি আপনি না করেন ' টির কোনও অদলবদল নেই, আপনাকে আপনার প্রায় অর্ধেক র‌্যাম বরাদ্দ করার অনুমতি দেওয়া হবে, এবং যদি আপনার অদলবদল হয়, আপনি আপনার প্রায় অর্ধেক র‌্যাম প্লাস আপনার সমস্ত সোয়াপ পাবেন। এটাই বা কম প্রক্রিয়া প্রতি (কিন্তু মনে রাখবেন এই সীমা নেই গতিশীল এবং কারণ রাষ্ট্রের পরিবর্তন সাপেক্ষে, পাদটীকা 5 কিছু পর্যবেক্ষণ দেখুন)।

"কমিটলিমিট" ফিল্ডের জন্য আপনার অর্ধেক র‌্যাম প্লাস সোয়াপ সুস্পষ্টভাবে ডিফল্ট /proc/meminfo। এখানে এর অর্থ কী - এখানে দেখুন এবং স্রেফ আলোচিত সীমাবদ্ধতার সাথে এর কিছুই করার নেই [src]/Documentation/filesystems/proc.txt:

কমিটলিমিট: ওভারকমিট অনুপাতের ভিত্তিতে ('vm.overcommit_ratio'), এটি বর্তমানে সিস্টেমে বরাদ্দকৃত মোট মেমরির পরিমাণ এই সীমাটি কেবলমাত্র কঠোরভাবে ওভারকমিট অ্যাকাউন্টিং সক্ষম করা থাকলে ('vm.overcommit_memory' 2 মোডে মোড) মেনে চলে। কমিটলিমিটটি নিম্নলিখিত সূত্র দিয়ে গণনা করা হয়: কমিটলিমিট = ('ভিএম.ওভার কমিট_রটিও' * শারীরিক র‌্যাম) + অদলবদলের উদাহরণস্বরূপ, 1 জি ফিজিক্যাল র‌্যামের একটি সিস্টেম এবং 30-এর একটি 'vm.overcommit_ratio' সহ অদলবদল 7G হবে 7.3 জি এর কমিটলিমিট।

পূর্বে উদ্ধৃত ওভারকমিট-অ্যাকাউন্টিং ডকটি সূচিত হয়েছে যে ডিফল্ট vm.overcommit_ratio50 হয় So তাই sysctl vm.overcommit_memory=2আপনি যদি তারপর vm.covercommit_ratio সামঞ্জস্য করতে পারেন (এর সাথে sysctl) এবং ফলাফলগুলি দেখতে পারেন। 3 ডিফল্ট মোড, যখন CommitLimitকার্যকরী হয় না এবং শুধুমাত্র "অ্যাড্রেস স্পেস এর সুস্পষ্ট overcommits প্রত্যাখ্যান করছে", যখন vm.overcommit_memory=0

ডিফল্ট কৌশলটিতে "গম্ভীরভাবে বন্য বরাদ্দ" রোধের প্রতি প্রক্রিয়াধর্মের একটি হিউরিস্টিক সীমাবদ্ধতা রয়েছে, তবে এটি সিস্টেমকে মারাত্মকভাবে বন্য হওয়ার জন্য সম্পূর্ণ বরাদ্দ দেয়, বরাদ্দ-ভিত্তিক 4 এর অর্থ এটি এক পর্যায়ে স্মৃতিশক্তি শেষ হয়ে যেতে পারে এবং OOM হত্যাকারীর মাধ্যমে কোনও প্রক্রিয়াতে (দে) দেউলিয়া ঘোষণা করতে হবে ।

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

এটি এখান থেকে উদ্ধৃত করা হয়েছে যা সম্ভবত একটি 2.6.x উত্স উদ্ধৃত করে:

/*
 * oom_badness - calculate a numeric value for how bad this task has been
 *
 * The formula used is relatively simple and documented inline in the
 * function. The main rationale is that we want to select a good task
 * to kill when we run out of memory.
 *
 * Good in this context means that:
 * 1) we lose the minimum amount of work done
 * 2) we recover a large amount of memory
 * 3) we don't kill anything innocent of eating tons of memory
 * 4) we want to kill the minimum amount of processes (one)
 * 5) we try to kill the process the user expects us to kill, this
 *    algorithm has been meticulously tuned to meet the principle
 *    of least surprise ... (be careful when you change it)
 */

যা শালীন যুক্তিযুক্ত বলে মনে হচ্ছে। তবে, ফরেনসিক না পেয়ে, # 5 (যা # 1 এর অপ্রয়োজনীয়) মনে হয় শক্ত বিক্রয় বাস্তবায়ন হিসাবে মনে হয়, এবং # 3 # 2 এর অপ্রয়োজনীয়। সুতরাং এটি # 2/3 এবং # 4 এ যুক্ত করা বিবেচনা করা বুদ্ধিমান হতে পারে।

আমি একটি সাম্প্রতিক উত্স (3.11) ধরে ফেলেছি এবং লক্ষ্য করেছি যে এই মন্তব্যটি অন্তর্বর্তীকালীনভাবে পরিবর্তিত হয়েছে:

/**
 * oom_badness - heuristic function to determine which candidate task to kill
 *
 * The heuristic for determining which task to kill is made to be as simple and
 * predictable as possible.  The goal is to return the highest value for the
 * task consuming the most memory to avoid subsequent oom failures.
 */

এটি # 2 সম্পর্কে কিছুটা স্পষ্টভাবে বলা যায়: "পরবর্তী ওম ব্যর্থতা এড়াতে সর্বাধিক স্মৃতি গ্রহণ করা কাজটি [হত্যা] করাই হ'ল লক্ষ্য", এবং জড়িত # 4 ( "আমরা ন্যূনতম পরিমাণ প্রক্রিয়াগুলিকে হত্যা করতে চাই ( এক ) )

আপনি যদি ওওএম ঘাতককে ক্রিয়াতে দেখতে চান তবে পাদটীকা 5 দেখুন।


1 একটি বিভ্রান্তি গিলস আমাকে কৃতজ্ঞতার সাথে মুক্ত করেছেন, মন্তব্য দেখুন।


2 এখানে সি এর একটি সরল বিট যা ক্রমবর্ধমান বৃহত অংশগুলি মেমরির বৃহত্তর অংশগুলি নির্ধারণ করতে যখন আরও বেশি জন্য একটি অনুরোধ ব্যর্থ হবে তা নির্ধারণ করতে বলে:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#define MB 1 << 20

int main (void) {
    uint64_t bytes = MB;
    void *p = malloc(bytes);
    while (p) {
        fprintf (stderr,
            "%lu kB allocated.\n",
            bytes / 1024
        );
        free(p);
        bytes += MB;
        p = malloc(bytes);
    }
    fprintf (stderr,
        "Failed at %lu kB.\n",
        bytes / 1024
    );
    return 0;
}            

আপনি যদি সি না জানেন তবে আপনি এটি সংকলন করতে পারেন gcc virtlimitcheck.c -o virtlimitcheck, তবে চালান ./virtlimitcheck। এটি সম্পূর্ণরূপে নিরীহ, কারণ প্রক্রিয়াটি যে জায়গাগুলির জন্য জিজ্ঞাসা করে তার কোনও স্থান ব্যবহার করে না - যেমন, এটি সত্যই কোনও র‌্যাম ব্যবহার করে না।

4 জিবি সিস্টেম এবং 6 গিগাবাইট অদলবদল সহ একটি 3.11 x86_64 সিস্টেমে আমি ব্যর্থ হয়েছি; 7400000 কেবি; সংখ্যা ওঠানামা করে, তাই সম্ভবত রাষ্ট্র একটি ফ্যাক্টর। এই কাকতালীয়ভাবে পাসে হবে CommitLimitমধ্যে /proc/meminfo, কিন্তু এই মাধ্যমে পরিবর্তন vm.overcommit_ratioকোনো পার্থক্য দেখা যায় না। একটি 6.6.১১ ৩২-বিট এআরএম ৪৪৮ এমবি সিস্টেমে MB৪ এমবি অদলবদল সহ, তবে আমি ব্যর্থ। 230 এমবি। এটি আকর্ষণীয় যেহেতু প্রথম ক্ষেত্রে পরিমাণটি প্রায় র্যামের পরিমাণের দ্বিগুণ, অন্যদিকে এটি প্রায় 1/4 যা - স্বাপের পরিমাণকে দৃ .়ভাবে বোঝানো একটি কারণ। এটি প্রথম সিস্টেমে অদলবদল করে নিশ্চিত করা হয়েছিল, যখন ব্যর্থতার প্রান্তটি down 1.95 গিগাবাইটে নেমে গিয়েছিল, এটি সামান্য এআরএম বাক্সের সাথে খুব অনুরূপ অনুপাত।

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

#include <stdio.h>
#include <stdlib.h>

#define MB 1 << 20

int main (int argc, const char *argv[]) {
    unsigned long int megabytes = strtoul(argv[1], NULL, 10);
    void *p = malloc(megabytes * MB);
    fprintf(stderr,"Allocating %lu MB...", megabytes);
    if (!p) fprintf(stderr,"fail.");
    else {
        fprintf(stderr,"success.");
        getchar();
        free(p);
    }
    return 0;
}

তবে সাবধান থাকুন যে এটি নির্বিশেষে র‌্যাম এবং অদলবদলের পরিমাণ সম্পর্কে কঠোরভাবে নয় - সিস্টেমের অবস্থার প্রভাবগুলি সম্পর্কে পর্যবেক্ষণের জন্য পাদটীকা 5 দেখুন।


3 সিস্টেমেরCommitLimit জন্য অনুমোদিত ঠিকানা জায়গার পরিমাণকে বোঝায় যখন vm.overcommit_memory = 2. সম্ভবত তখন, আপনি যে পরিমাণ পরিমাণ বরাদ্দ করতে পারবেন তা ইতিমধ্যে প্রতিশ্রুতিবদ্ধ হওয়া উচিত, যা দৃশ্যত ক্ষেত্র isCommitted_AS

এটি প্রদর্শিত একটি সম্ভাব্য আকর্ষণীয় পরীক্ষা #include <unistd.h>হ'ল ভ্যালিমিচেকেক.কে শীর্ষে যোগ করুন (পাদটীকা 2 দেখুন) এবং লুপের fork()ঠিক আগে while()। কিছু ক্লান্তিকর সিঙ্ক্রোনাইজেশন ছাড়াই এখানে বর্ণিত হিসাবে কাজ করার গ্যারান্টিযুক্ত নয়, তবে এটি করার একটি শালীন সুযোগ রয়েছে, ওয়াইএমএমভি:

> sysctl vm.overcommit_memory=2
vm.overcommit_memory = 2
> cat /proc/meminfo | grep Commit
CommitLimit:     9231660 kB
Committed_AS:    3141440 kB
> ./virtlimitcheck 2&> tmp.txt
> cat tmp.txt | grep Failed
Failed at 3051520 kB.
Failed at 6099968 kB.

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


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


5 প্রথমে একটি সতর্কতা : আপনি যদি এটি দিয়ে চেষ্টা করে থাকেন তবে vm.overcommit_memory=0নিশ্চিত হয়ে নিন যে আপনি নিজের কাজটি প্রথমে সংরক্ষণ করেছেন এবং কোনও সমালোচনামূলক অ্যাপ্লিকেশন বন্ধ করেছেন, কারণ সিস্টেমটি 90 ডলার সেকেন্ডের জন্য হিমায়িত হবে এবং কিছু প্রক্রিয়া মারা যাবে!

ধারণাটি হ'ল কাঁটাচামচ বোমা চালানো হবে যা 90 সেকেন্ড পরে বেরিয়ে আসে, কাঁটাচামচ দিয়ে জায়গা বরাদ্দ দেওয়া হয় এবং তাদের মধ্যে কিছু লোক র‌্যামকে প্রচুর পরিমাণে ডেটা লেখেন, স্টারডারকে প্রতিবেদন করার সময়।

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <errno.h>
#include <string.h>

/* 90 second "Verbose hungry fork bomb".
Verbose -> It jabbers.
Hungry -> It grabs address space, and it tries to eat memory.

BEWARE: ON A SYSTEM WITH 'vm.overcommit_memory=0', THIS WILL FREEZE EVERYTHING
FOR THE DURATION AND CAUSE THE OOM KILLER TO BE INVOKED.  CLOSE THINGS YOU CARE
ABOUT BEFORE RUNNING THIS. */

#define STEP 1 << 30 // 1 GB
#define DURATION 90

time_t now () {
    struct timeval t;
    if (gettimeofday(&t, NULL) == -1) {
        fprintf(stderr,"gettimeofday() fail: %s\n", strerror(errno));
        return 0;
    }
    return t.tv_sec;
}

int main (void) {
    int forks = 0;
    int i;
    unsigned char *p;
    pid_t pid, self;
    time_t check;
    const time_t start = now();
    if (!start) return 1;

    while (1) {
    // Get our pid and check the elapsed time.
        self = getpid();
        check = now();
        if (!check || check - start > DURATION) return 0;
        fprintf(stderr,"%d says %d forks\n", self, forks++);
    // Fork; the child should get its correct pid.
        pid = fork();
        if (!pid) self = getpid();
    // Allocate a big chunk of space.
        p = malloc(STEP);
        if (!p) {
            fprintf(stderr, "%d Allocation failed!\n", self);
            return 0;
        }
        fprintf(stderr,"%d Allocation succeeded.\n", self);
    // The child will attempt to use the allocated space.  Using only
    // the child allows the fork bomb to proceed properly.
        if (!pid) {
            for (i = 0; i < STEP; i++) p[i] = i % 256;
            fprintf(stderr,"%d WROTE 1 GB\n", self);
        }
    }
}                        

এটি সঙ্কলন gcc forkbomb.c -o forkbomb। প্রথমে এটি ব্যবহার করে দেখুন sysctl vm.overcommit_memory=2- আপনি সম্ভবত কিছু পাবেন:

6520 says 0 forks
6520 Allocation succeeded.
6520 says 1 forks
6520 Allocation succeeded.
6520 says 2 forks
6521 Allocation succeeded.
6520 Allocation succeeded.
6520 says 3 forks
6520 Allocation failed!
6522 Allocation succeeded.

এই পরিবেশে, এই ধরণের কাঁটাচামচ বোমা খুব বেশি পাওয়া যায় না। নোট করুন যে "এন ফর্কস বলে" এর সংখ্যাটি মোট প্রক্রিয়াগুলির সংখ্যা নয়, এটি শৃঙ্খলা / শাখায় যে প্রক্রিয়াটি তৈরি করে তার সংখ্যা।

এখন এটি দিয়ে চেষ্টা করুন vm.overcommit_memory=0। আপনি যদি স্টাডারকে কোনও ফাইলে পুনর্নির্দেশ করেন তবে আপনি পরে কিছু অশোধিত বিশ্লেষণ করতে পারেন, যেমন:

> cat tmp.txt | grep failed
4641 Allocation failed!
4646 Allocation failed!
4642 Allocation failed!
4647 Allocation failed!
4649 Allocation failed!
4644 Allocation failed!
4643 Allocation failed!
4648 Allocation failed!
4669 Allocation failed!
4696 Allocation failed!
4695 Allocation failed!
4716 Allocation failed!
4721 Allocation failed!

প্রদর্শক overcommit_memory = 0 জন্য অনুসন্ধানমূলক - কেবলমাত্র 15 প্রসেস 1 গিগাবাইট বরাদ্দ করতে ব্যর্থ হয় রাষ্ট্র দ্বারা প্রভাবিত। সেখানে কতগুলি প্রক্রিয়া ছিল? Tmp.txt এর শেষে খুঁজছেন, সম্ভবত> 100,000। এখন কীভাবে আসলে 1 জিবি ব্যবহার করতে পারা যায়?

> cat tmp.txt | grep WROTE
4646 WROTE 1 GB
4648 WROTE 1 GB
4671 WROTE 1 GB
4687 WROTE 1 GB
4694 WROTE 1 GB
4696 WROTE 1 GB
4716 WROTE 1 GB
4721 WROTE 1 GB

আট - যা আবার অর্থবোধ করে, যেহেতু সেই সময়টিতে আমার কাছে 3 গিগাবাইট র‌্যাম ফ্রি এবং 6 জিবি স্বাপ ছিল।

এটি করার পরে আপনার সিস্টেম লগগুলিতে একবার দেখুন। আপনার OOM হত্যাকারী রিপোর্টিং স্কোরগুলি দেখতে হবে (অন্যান্য জিনিসের মধ্যে); সম্ভবত এটির সাথে সম্পর্কিত oom_badness


অদলবদল প্রতিশ্রুতি উপর মেমরি একটি সমাধান (বা এমনকি সম্পর্কিত) নয়। মেমরি বরাদ্দ (যেমন: malloc) ভার্চুয়াল মেমরির সংরক্ষণ করার অনুরোধ সম্পর্কে, শারীরিক নয়।
jlliagre

1
@ জিলাগ্রে: "অদলবদল প্রতিশ্রুতি দিয়ে স্মৃতিচারণের সমাধান (বা এমনকি সম্পর্কিত) নয়" -> হ্যাঁ, আসলে এটি। প্রায়শই ব্যবহৃত পৃষ্ঠাগুলি র‌্যামের বাইরে চলে যায়, যা ডিমান্ড পেজিং / বরাদ্দের কারণে সৃষ্ট পৃষ্ঠা ত্রুটিগুলি মোকাবেলা করার জন্য আরও র‌্যাম উপলব্ধ থাকে (এটি সেই ব্যবস্থা যা প্রতিশ্রুতি অর্জন সম্ভব করে তোলে)। অদলবদল করা পৃষ্ঠাগুলি কোনও সময়ে ডিমে পেজ করে র‌্যামে যেতে পারে।
স্বর্ণিলোক

"মেমোরি বরাদ্দ (উদাঃ malloc) ভার্চুয়াল মেমরির সংরক্ষণের অনুরোধ সম্পর্কে, শারীরিক নয়।" -> ডান, তবে শারীরিক ম্যাপিংগুলি যখন বাকী নেই তখন কার্নেলটি (এবং optionচ্ছিকভাবে, না) বলতে পারে না । এটি অবশ্যই হবে না কারণ কোনও প্রক্রিয়া ভার্চুয়াল অ্যাড্রেস স্পেসের বাইরে চলে গেছে (বা কমপক্ষে সাধারণত না, যেহেতু এটিও সম্ভব, কমপক্ষে 32-বিট সিস্টেমে)।
স্বর্ণলোকস

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

"ডিমান্ড পেজিং যা প্রতিশ্রুতি দিয়ে স্মৃতিকে সম্ভব করে তোলে তা নয়।" -> সম্ভবত এটি বলা ভাল যে এটি ভার্চুয়াল সম্বোধন যা চাহিদা মঞ্জুরি এবং প্রতিশ্রুতি উভয়ই সম্ভব করে তোলে। "লিনাক্স অবশ্যই অদলবদলের কোনও অঞ্চল নেই এমন সিস্টেমে মেমরি প্রতিশ্রুতি দেয়।" -> অবশ্যই, যেহেতু ডিমান্ড পেজিংয়ের জন্য অদলবদলের প্রয়োজন হয় না; অদলবদল থেকে ডিমান্ড পেজিং হ'ল ডিমান্ড পেজিংয়ের একটি বিশেষ উদাহরণ। আবার, swap 'র হয় উপর অঙ্গীকার একটি সমাধান অর্থে এটি সমস্যা solves নেই, কিন্তু জ্ঞান সম্ভাব্য হলে OOM kills ঘটনা প্রতিশ্রুতি থেকে ফল পারে প্রতিরোধ সাহায্য করবে না।
স্বর্ণলোকস

16

আপনি যদি কখনও মেমরিতে 1G ডেটা লোড করেন তবে এটি আপনার ক্ষেত্রে ঘটবে না। যদি আপনি আরও অনেক বেশি লোড করেন? উদাহরণস্বরূপ, আমি প্রায়শই লক্ষাধিক সম্ভাবনাযুক্ত বিশাল ফাইলগুলির সাথে কাজ করি যা আর এর মধ্যে লোড করা দরকার This এতে প্রায় 16 গিগাবাইট র‌্যাম লাগে।

আমার ল্যাপটপে উপরের প্রক্রিয়াটি চালনা করায় এটি আমার 8 জিবি র‌্যাম পূরণের সাথে সাথেই পাগলের মতো বদলে যাওয়া শুরু করবে। এটি, পরিবর্তে, সমস্ত কিছু কমিয়ে দেবে কারণ র‌্যাম থেকে পড়ার চেয়ে ডিস্ক থেকে পড়া অনেক ধীর। আমার কাছে যদি 2 জিবি র‌্যাম এবং কেবল 10 জিবি ফাঁকা জায়গা সহ একটি ল্যাপটপ থাকে? প্রক্রিয়াটি সমস্ত র‌্যাম গ্রহণ করার পরে, এটি ডিস্কটি পূরণ করবে কারণ এটি অদলবদল করার জন্য লিখতে চলেছে এবং আমার আর কোনও র‌্যাম নেই এবং তার মধ্যে আর কোনও অদলবদল করার মতো জায়গা নেই (লোকেরা স্ব্যাপের পরিবর্তে ডেডিকেটেড পার্টিশনে সীমাবদ্ধ রাখে tend ঠিক যে কারণে swapfile)। সেখানেই ওওএম ঘাতক আসে এবং হত্যা প্রক্রিয়া শুরু করে।

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


5

আর কোনও র‌্যাম না থাকলে প্রক্রিয়াগুলি হত্যা করা হয় না, এইভাবে প্রতারণা করা হলে তাদের হত্যা করা হয়:

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

সিস্টেমটি সক্রিয়ভাবে অদলবদল না করার পরেও এটি ঘটতে পারে, উদাহরণস্বরূপ যদি অদলবদলটি স্লিপিং ডেমনস মেমরি পৃষ্ঠাগুলিতে পূর্ণ হয়।

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


3

যখন উপলব্ধ র‌্যাম নিঃশেষ হয়ে যায়, তখন কার্নেলটি ডিস্কে প্রসেসিংয়ের বিটগুলি সরিয়ে নিতে শুরু করে। প্রকৃতপক্ষে, যখন র‌্যাম ক্লান্তির কাছাকাছি হয় তখন কার্নেলটি অদলবদল শুরু করে: এটি একটি অলস মুহূর্ত থাকা অবস্থায় এটি সক্রিয়ভাবে অদলবদল শুরু করে, যাতে কোনও অ্যাপ্লিকেশনটিতে হঠাৎ আরও মেমরির প্রয়োজন হলে আরও প্রতিক্রিয়াশীল হতে পারে।

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

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

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

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

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

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


2

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


-1

কিছু সময় লিনাক্স বাহ্যিক ভার্চুয়াল স্থান নেয় takes সেটি হল অদলবদল বিভাজন। যখন রাম ভরা থাকে লিনাক্স এই অদলবদলটিকে কম অগ্রাধিকার প্রক্রিয়া চালায় takes


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