লিনাক্স মেমরি পরিচালনায় আরএসএস এবং ভিএসজেড কী


331

লিনাক্স মেমরি পরিচালনায় আরএসএস এবং ভিএসজেড কী কী? বহুবিবাহিত পরিবেশে এই দু'জনকেই কীভাবে পরিচালনা ও ট্র্যাক করা যায়?


উত্তর:


499

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

ভিএসজেড ভার্চুয়াল মেমরির আকার Size এতে প্রক্রিয়াটি অ্যাক্সেস করতে পারে এমন সমস্ত মেমরি অন্তর্ভুক্ত রয়েছে, যা অদলবদল হওয়া মেমরি, বরাদ্দ হওয়া, তবে ব্যবহৃত হয়নি এমন মেমরি এবং ভাগ করা লাইব্রেরি থেকে প্রাপ্ত মেমরি সহ।

সুতরাং যদি প্রক্রিয়া A এর 500K বাইনারি থাকে এবং 2500 কে ভাগ করে নেওয়া গ্রন্থাগারগুলির সাথে সংযুক্ত থাকে, 200K স্ট্যাক / হিপ বরাদ্দ থাকে যার মধ্যে 100K আসলে মেমরিতে থাকে (বাকীটি অদলবদল বা অব্যবহৃত হয়), এবং এটি আসলে ভাগ করা লাইব্রেরিগুলির 1000K লোড করেছে এবং এর পরে তার নিজস্ব বাইনারি 400K:

RSS: 400K + 1000K + 100K = 1500K
VSZ: 500K + 2500K + 200K = 3200K

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

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

পিএসএস (আনুপাতিক সেট আকার )ও রয়েছে। এটি একটি নতুন পরিমাপ যা বর্তমান প্রক্রিয়া দ্বারা ব্যবহৃত অনুপাত হিসাবে ভাগ করা মেমরিটিকে ট্র্যাক করে। সুতরাং যদি আগে থেকে একই ভাগ করা লাইব্রেরি ব্যবহার করে দুটি প্রক্রিয়া থাকে:

PSS: 400K + (1000K/2) + 100K = 400K + 500K + 100K = 1000K

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

এর চেয়ে আরও অনেক উপায় আছে, নিম্নলিখিত রেফারেন্সগুলি আরও পরীক্ষা করতে শিখুন:

আরও দেখুন:


17
আমি বিশ্বাস করি আরএসএস করে পরিবর্তনশীল লিঙ্ক লাইব্রেরী থেকে মেমরি অন্তর্ভুক্ত। যদি 3 টি প্রক্রিয়া ব্যবহার করে থাকে libxml2.so, তবে ভাগ করা গ্রন্থাগারটি তাদের প্রতিটি আরএসএসে গণনা করা হবে, সুতরাং তাদের আরএসএসের যোগফল ব্যবহৃত প্রকৃত মেমরির চেয়ে বেশি হবে।
nfm

1
ঐটা ঠিক. আমি আমার উত্তর স্থির করেছি, মাথা আপ জন্য ধন্যবাদ।
jmh

আমি উবুন্টু ১.0.০৪ এ আছি এবং সেখানে একটি জাভা প্রক্রিয়া রয়েছে যার topকমান্ড থেকে 1.2G আরএস এবং 4.5 জি ভিআরটি প্রদর্শিত হচ্ছে । এই সিস্টেমে কোনও অদলবদল নেই, swapon --showকিছুই দেয় না। আপনি এটা কিভাবে ব্যাখ্যা করবেন? যদি vsz যদি অদলবদল + ভাগ করা লাইব্রেরি হয় তবে এই ক্ষেত্রে ভাগ করা লাইব্রেরিগুলি 3.3G এরও বেশি? এটা কি সম্ভব? ঠিক সত্যই বিভ্রান্ত ...
অ্যারন ওয়াং

আমি সত্যিই নিশ্চিত নই। জাভা ভার্চুয়াল মেমরির ব্যবহার সম্পর্কে এই উত্তরটি একবার দেখুন: stackoverflow.com/a/561450/622115 । সংক্ষিপ্ত সংস্করণ: ভিএসজেডে হ্যাপ স্পেস অন্তর্ভুক্ত থাকতে পারে যা বরাদ্দ করা হয় এবং মেমরি ম্যাপযুক্ত ফাইলগুলির পাশাপাশি ব্যবহার করা হয় না।
jmh

গ্রেট। শুধু কিছু যোগ করুন। যদি আপনি malloc (100KB) করেন তবে কেবলমাত্র 1KB ব্যবহার করুন। আরএসএস 1K এবং বনাম 100 কিল, এমনকি এখানে কোনও অদলবদল না থাকলেও।
কেনে ভ্যান

53

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

নোট করুন যে কমনপ্লেস ভার্চুয়াল মেশিনগুলির এই দিনগুলিতে, মেশিনের ভিউ পয়েন্ট থেকে শারীরিক মেমরি সত্যিই প্রকৃত শারীরিক মেমরির নাও হতে পারে।


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

10

ন্যূনতম চলমান উদাহরণ

এটি বোঝার জন্য, আপনাকে পেজিংয়ের মূল বিষয়গুলি বুঝতে হবে: x86 পেজিং কীভাবে কাজ করে? এবং বিশেষত র‍্যাম বা ডিস্কে আরএসএসের বাসিন্দা মেমরির ব্যাকিং স্টোরেজ হওয়ার আগে ওএস পৃষ্ঠাগুলি / তার অভ্যন্তরীণ মেমরি বই রাখার (ভিএসজেড ভার্চুয়াল মেমরি) মাধ্যমে ভার্চুয়াল মেমরির বরাদ্দ করতে পারে।

এখন এটি কার্যকরভাবে পর্যবেক্ষণ করতে, আসুন একটি প্রোগ্রাম তৈরি করুন যা:

  • আমাদের শারীরিক মেমরির চেয়ে আরও বেশি র‌্যাম বরাদ্দ করে mmap
  • এই পৃষ্ঠাগুলির প্রত্যেকটি ভার্চুয়াল কেবল মেমরি (ভিএসজেড) থেকে প্রকৃত ব্যবহৃত মেমরি (আরএসএস) এ যায় তা নিশ্চিত করার জন্য প্রতিটি পৃষ্ঠায় একটি বাইট লিখেছেন
  • উল্লিখিত একটি পদ্ধতির সাহায্যে প্রক্রিয়াটির স্মৃতি ব্যবহার পরীক্ষা করে: সিটিতে বর্তমান প্রক্রিয়ার মেমরির ব্যবহার

main.c

#define _GNU_SOURCE
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

typedef struct {
    unsigned long size,resident,share,text,lib,data,dt;
} ProcStatm;

/* /programming/1558402/memory-usage-of-current-process-in-c/7212248#7212248 */
void ProcStat_init(ProcStatm *result) {
    const char* statm_path = "/proc/self/statm";
    FILE *f = fopen(statm_path, "r");
    if(!f) {
        perror(statm_path);
        abort();
    }
    if(7 != fscanf(
        f,
        "%lu %lu %lu %lu %lu %lu %lu",
        &(result->size),
        &(result->resident),
        &(result->share),
        &(result->text),
        &(result->lib),
        &(result->data),
        &(result->dt)
    )) {
        perror(statm_path);
        abort();
    }
    fclose(f);
}

int main(int argc, char **argv) {
    ProcStatm proc_statm;
    char *base, *p;
    char system_cmd[1024];
    long page_size;
    size_t i, nbytes, print_interval, bytes_since_last_print;
    int snprintf_return;

    /* Decide how many ints to allocate. */
    if (argc < 2) {
        nbytes = 0x10000;
    } else {
        nbytes = strtoull(argv[1], NULL, 0);
    }
    if (argc < 3) {
        print_interval = 0x1000;
    } else {
        print_interval = strtoull(argv[2], NULL, 0);
    }
    page_size = sysconf(_SC_PAGESIZE);

    /* Allocate the memory. */
    base = mmap(
        NULL,
        nbytes,
        PROT_READ | PROT_WRITE,
        MAP_SHARED | MAP_ANONYMOUS,
        -1,
        0
    );
    if (base == MAP_FAILED) {
        perror("mmap");
        exit(EXIT_FAILURE);
    }

    /* Write to all the allocated pages. */
    i = 0;
    p = base;
    bytes_since_last_print = 0;
    /* Produce the ps command that lists only our VSZ and RSS. */
    snprintf_return = snprintf(
        system_cmd,
        sizeof(system_cmd),
        "ps -o pid,vsz,rss | awk '{if (NR == 1 || $1 == \"%ju\") print}'",
        (uintmax_t)getpid()
    );
    assert(snprintf_return >= 0);
    assert((size_t)snprintf_return < sizeof(system_cmd));
    bytes_since_last_print = print_interval;
    do {
        /* Modify a byte in the page. */
        *p = i;
        p += page_size;
        bytes_since_last_print += page_size;
        /* Print process memory usage every print_interval bytes.
         * We count memory using a few techniques from:
         * /programming/1558402/memory-usage-of-current-process-in-c */
        if (bytes_since_last_print > print_interval) {
            bytes_since_last_print -= print_interval;
            printf("extra_memory_committed %lu KiB\n", (i * page_size) / 1024);
            ProcStat_init(&proc_statm);
            /* Check /proc/self/statm */
            printf(
                "/proc/self/statm size resident %lu %lu KiB\n",
                (proc_statm.size * page_size) / 1024,
                (proc_statm.resident * page_size) / 1024
            );
            /* Check ps. */
            puts(system_cmd);
            system(system_cmd);
            puts("");
        }
        i++;
    } while (p < base + nbytes);

    /* Cleanup. */
    munmap(base, nbytes);
    return EXIT_SUCCESS;
}

গিটহাব উজানের দিকে

সংকলন এবং চালান:

gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
echo 1 | sudo tee /proc/sys/vm/overcommit_memory
sudo dmesg -c
./main.out 0x1000000000 0x200000000
echo $?
sudo dmesg

কোথায়:

  • 0x1000000000 == 64GiB: 2x আমার কম্পিউটারের 32GiB এর দৈহিক র‌্যাম
  • 0x200000000 == 8GiB: প্রতি 8GiB মেমরিটি মুদ্রণ করুন, তাই প্রায় 32GiB এ ক্র্যাশ হওয়ার আগে আমাদের 4 টি প্রিন্ট পাওয়া উচিত
  • echo 1 | sudo tee /proc/sys/vm/overcommit_memory: লিনাক্সের জন্য আমাদের দৈহিক র্যামের চেয়ে বড় একটি এমএমএপ কল করার অনুমতি দেওয়ার জন্য প্রয়োজনীয়: সর্বাধিক মেমরি যা ম্যালোক বরাদ্দ করতে পারে

প্রোগ্রাম আউটপুট:

extra_memory_committed 0 KiB
/proc/self/statm size resident 67111332 768 KiB
ps -o pid,vsz,rss | awk '{if (NR == 1 || $1 == "29827") print}'
  PID    VSZ   RSS
29827 67111332 1648

extra_memory_committed 8388608 KiB
/proc/self/statm size resident 67111332 8390244 KiB
ps -o pid,vsz,rss | awk '{if (NR == 1 || $1 == "29827") print}'
  PID    VSZ   RSS
29827 67111332 8390256

extra_memory_committed 16777216 KiB
/proc/self/statm size resident 67111332 16778852 KiB
ps -o pid,vsz,rss | awk '{if (NR == 1 || $1 == "29827") print}'
  PID    VSZ   RSS
29827 67111332 16778864

extra_memory_committed 25165824 KiB
/proc/self/statm size resident 67111332 25167460 KiB
ps -o pid,vsz,rss | awk '{if (NR == 1 || $1 == "29827") print}'
  PID    VSZ   RSS
29827 67111332 25167472

Killed

প্রস্থান স্থিতি:

137

যার 128 + সিগন্যাল নম্বর বিধি অনুসারে আমরা সিগন্যাল নম্বর পেয়েছি 9, যা man 7 signalবলে সিগ্কিল , যা লিনাক্স মেমরির বহির্মুখী কিলার দ্বারা প্রেরণ করা হয়েছিল ।

আউটপুট ব্যাখ্যা:

  • ভিএমজেড ভার্চুয়াল মেমরি এমএমএপের পরে printf '0x%X\n' 0x40009A4 KiB ~= 64GiB( psমানগুলি কিবিতে থাকে) স্থির থাকে ।
  • আরএসএসের "আসল মেমরির ব্যবহার" কেবল পৃষ্ঠাগুলি স্পর্শ করার সাথে সাথে অলসতা বাড়ায়। উদাহরণ স্বরূপ:
    • প্রথম মুদ্রণে, আমাদের রয়েছে extra_memory_committed 0, যার অর্থ আমরা এখনও কোনও পৃষ্ঠা স্পর্শ করি নি। আরএসএস একটি ছোট 1648 KiBযা পাঠ্য অঞ্চল, গ্লোবাল ইত্যাদির মতো সাধারণ প্রোগ্রাম স্টার্টআপের জন্য বরাদ্দ করা হয়েছে is
    • দ্বিতীয় প্রিন্টে, আমরা 8388608 KiB == 8GiBমূল্যবান পৃষ্ঠাগুলিতে লিখেছি । ফলস্বরূপ, আরএসএস ঠিক 8GIB দ্বারা বৃদ্ধি পেয়েছে8390256 KiB == 8388608 KiB + 1648 KiB
    • আরএসএস 8 জিআইবি ইনক্রিমেন্টে বৃদ্ধি অব্যাহত রেখেছে। শেষ মুদ্রণটি প্রায় 24 জিআইবি মেমরি দেখায় এবং 32 জিআইবি মুদ্রিত হওয়ার আগে ওওএম হত্যাকারী প্রক্রিয়াটিকে হত্যা করে

আরও দেখুন: /unix/35129/need-explanation-on-resident-set-size-virtual-size

ওম কিলার লগ

আমাদের dmesgআদেশগুলি OOM হত্যাকারী লগগুলি দেখিয়েছে।

এগুলির একটি সঠিক ব্যাখ্যা এখানে জিজ্ঞাসা করা হয়েছে:

লগের প্রথম লাইনটি ছিল:

[ 7283.479087] mongod invoked oom-killer: gfp_mask=0x6200ca(GFP_HIGHUSER_MOVABLE), order=0, oom_score_adj=0

সুতরাং আমরা দেখতে পেলাম যে মংগডিবি ডিমনটি সর্বদা আমার ল্যাপটপে পটভূমিতে চালিত হয় যেটি OOM হত্যাকারীকে প্রথমে ট্রিগার করেছিল, সম্ভবতঃ যখন দুর্বল জিনিস কিছু স্মৃতি বরাদ্দ করার চেষ্টা করছিল।

তবে ওওম ঘাতক যে জাগ্রত হয়েছিল তাকে অগত্যা হত্যা করে না।

অনুরোধের পরে, কার্নেল একটি টেবিল বা প্রক্রিয়াগুলি সহ প্রিন্ট করে oom_score:

[ 7283.479292] [  pid  ]   uid  tgid total_vm      rss pgtables_bytes swapents oom_score_adj name
[ 7283.479303] [    496]     0   496    16126        6   172032      484             0 systemd-journal
[ 7283.479306] [    505]     0   505     1309        0    45056       52             0 blkmapd
[ 7283.479309] [    513]     0   513    19757        0    57344       55             0 lvmetad
[ 7283.479312] [    516]     0   516     4681        1    61440      444         -1000 systemd-udevd

এবং আরও এগিয়ে আমরা দেখতে পাই যে আমাদের নিজের main.outছোট্টটি আগের অনুরোধে মারা গিয়েছিল:

[ 7283.479871] Out of memory: Kill process 15665 (main.out) score 865 or sacrifice child
[ 7283.479879] Killed process 15665 (main.out) total-vm:67111332kB, anon-rss:92kB, file-rss:4kB, shmem-rss:30080832kB
[ 7283.479951] oom_reaper: reaped process 15665 (main.out), now anon-rss:0kB, file-rss:0kB, shmem-rss:30080832kB

এই লগটিতে সেই score 865প্রক্রিয়াটি উল্লেখ করা হয়েছে , সম্ভবত উল্লিখিত হিসাবে সর্বোচ্চ (সবচেয়ে খারাপ) ওওএম ঘাতক স্কোরটি ছিল: /unix/153585/how-does-the-oom-killer-decide- who- প্রক্রিয়া-টু-কিল প্রথম

এছাড়াও মজার বিষয় হল, দৃশ্যত সবকিছু এত তাড়াতাড়ি ঘটেছিল যে মুক্ত মেমরির হিসাব হওয়ার আগে প্রক্রিয়াটি oomআবার জেগে ওঠে DeadlineMonitor:

[ 7283.481043] DeadlineMonitor invoked oom-killer: gfp_mask=0x6200ca(GFP_HIGHUSER_MOVABLE), order=0, oom_score_adj=0

এবং এই মুহুর্তে কিছু ক্রোমিয়াম প্রক্রিয়া নিহত হয়েছে যা সাধারণত আমার কম্পিউটারগুলি সাধারণ মেমরি হগ:

[ 7283.481773] Out of memory: Kill process 11786 (chromium-browse) score 306 or sacrifice child
[ 7283.481833] Killed process 11786 (chromium-browse) total-vm:1813576kB, anon-rss:208804kB, file-rss:0kB, shmem-rss:8380kB
[ 7283.497847] oom_reaper: reaped process 11786 (chromium-browse), now anon-rss:0kB, file-rss:0kB, shmem-rss:8044kB

উবুন্টু 19.04, লিনাক্স কার্নেল 5.0.0 এ পরীক্ষিত।


8

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


আপনি কি প্রেমের "লিনাক্স কার্নেল ডেভলপমেন্ট" বইটি উল্লেখ করছেন?
বেনজিমিন

1

এগুলি পরিচালনা করা হয় না, তবে পরিমাপ করা হয় এবং সম্ভবত সীমাবদ্ধ থাকে ( getrlimitসিস্টেম কলটি দেখুন, গেট্রিমিট (2) ) এও ।

আরএসএস অর্থ আবাসিক সেট আকার (র‌্যামে বসে আপনার ভার্চুয়াল ঠিকানার জায়গার অংশ)।

আপনি খোঁজ করতে পারেন ভার্চুয়াল অ্যাড্রেস স্পেস ব্যবহার প্রক্রিয়া 1234 এর proc (5) সঙ্গে cat /proc/1234/mapsপুরনো এবং (মেমরি খরচ সহ) এটির স্থিতিcat /proc/1234/status


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

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