یادگرفتن از یک پرسش: خطای محدودیت میزان حافظه limits.conf

یک مزیت بزرگ لینوکس برای من اینه که توش حل مشکلات می تونن منجر به چیز یاد گرفتن و پیشرفت مهارت ها و دانش آدم بشن. چنین چیزی وقتی راه حل همیشه «دوباره نصب کن» یا «فلان برنامه رو نصب و اجرا کن ببین مشکل حل می شه یا نه» باشه، اتفاق نمی افته. مثلا به این مورد نگاه کنین:

توی فروم فدورا اکبر پرسیده:

سلام خدمت دوستان
وقتی برنامه ardour 2.8.12 را اجرا میکنم پیغام زیر ظاهر میشه البته داخل پیام توضیحاتی داده که احتیاج اطلاعات تخصصی داره:

WARNING: Your system has a limit for maximum amount of locked memory. This might cause Ardour to run out of memory before your system runs out of memory.
You can view the memory limit with ‘ulimit -l’, and it is normally controlled by /etc/security/limits.conf

خب من جواب خیلی دقیق رو نمی دونم. ایده هایی در مورد لیمیت ها، page‌کردن در لینوکس و مدیریت حافظه دارم ولی این مورد به نظر چیز جالبی می یاد و فرصتی است برای یاد گرفتن. اول دستور ulimit رو با man ulimit یاد می گیرم. گفته با سوییچ a- میشه محدودیت ها رو دید. من مال خودم رو چک می کنم:

jadi@jubung:~$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 62804
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 62804
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

و می بینم که محدودیت لاک حافظه برای من ۶۴ کیلوبایت است. این یعنی کاربر من فقط حق داره ۶۴ کیلوبایت حافظه رو لاک کنه و احتمالا مربوط به تابع mlock توی برنامه نویسی. از اینجا شروع به سرچ می کنم و با ترکیب سرچ ها و خونده ها و اطلاعات شخصی ام به نتایج جالبی می رسم.

می دونیم که برنامه ها برای اجرا به حافظه احتیاج دارن. این حافظه معمولا از طریق تعریف متغیر و اینجور چیزها اشغال می شه و این سیستم عامل است که تصمیم می گیره چقدر از این اطلاعات رو واقعا توی مموری رم نگه داره و چقدر از اون رو page کنه توی swap. بذار یک کم برگردیم عقب.

لینوس که اولین بار کرنل رو نوشت، کامپیوترش مشکل کمبود رم داشت. حتی راحت نمی تونست بعضی چیزها رو کمپایل کنه. لینوس یک ابتکار زد – که البته شناخته شده بود ولی از یک کرنل دانشجویی انتظارش نمی رفت – و اونهم این بود که هر بار کامپیوتر رم کم می آورد، بخشی از رم فعلی که در این لحظه مورد استفاده نبود رو روی دیسک می نوشت و بعدا که رم خالی می شد راحت کارهاش رو می کرد و اگر هم در آینده کسی با اون بخش page out شده رم کار داشت، دوباره می رفت از رو دیسک اونو می خوند و می آورد توی رم تحویل برنامه محتاجش می داد. این یک انقلاب بود و خیلی از کسانی که اولین بار لینوکس رو می دیدن، شیفته این قابلیت می شد که می ذاشت شما روی یک کامپیوتر ضعیف، هر کار بزرگی رو با صبر و حوصله انجام بدین. در اصل با این ایده مفهوم «رم کم آوردن» دیگه از بین رفته بود.

همین حالا هم اون پارتیشن swap که درست می کنیم دقیقا کارش همینه. حتی اگر دستور top رو بزنی در دو خط آخر هدر این رو می بینی:

top - 11:00:56 up 1 day, 23:02,  5 users,  load average: 1.06, 1.08, 1.22
Tasks: 230 total,   2 running, 227 sleeping,   0 stopped,   1 zombie
Cpu(s):  9.2%us,  6.6%sy,  0.0%ni, 84.2%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   8062928k total,  7358752k used,   704176k free,   139228k buffers
Swap:  8395772k total,    59136k used,  8336636k free,  2854564k cached

که می گه کامپیوتر من هشت گیگ رم واقعی داره و اگر اون کم بیاد می تونه هشت گیگش رو هم روی دیسک بنویسه و از دیسک به عنوان رم استفاده کنه (زیاد رم دارم؟ اصلا.. رم مهمترین چیز در کامپیوتره و خیلی هم ارزونه. من ترجیح می دم به جای ای۷، آی۵ داشته باشیم ولی هشت گیگ رم رو از دست ندم).

اما ممکنه یک برنامه به هردلیلی بخواد جلوی اینکار رو بگیره و مطمئن باشه که براش فلان مقدار رم واقعی از پیش کنار گذاشته شده! تابع mlock اینکار رو می کنه. من می تونم موقع برنامه نویسی به سیستم عامل دستور بدم که «برای من یک مگ رم واقعی بذار کنار، به هیچ کس نده اونو و pageش هم نکن و بذار توی رم آماده به کار باشه». خب اینو همه برنامه ها دوست خواهند داشت از جمله برنامه ضبط صدای تو که چون داره صدای حرفه ای ضبط می کنه اصلا نباید منتظر دیسک و حافظه خالی نبودن و اینها باشه پس سعی می کنه وقتی می یاد بالا برای خودش یک حافظه اختصاصی درخواست کنه.

اما توی سیستم عامل دیدیم که گفتیم:‌

jadi@jubung:~$ ulimit -a | grep memory
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
virtual memory          (kbytes, -v) unlimited

یعنی محدودیتی برای کاربر گذاشتیم که کلا همه برنامه های این کاربر روی هم نتونن بیشتر از ۶۴ کیلوبایت حافظه رو تا لحظه که می خوان توی خود رم واقعی به خودشون اختصاص بدن. این عدد خیلی کوچیکه و در اصل معنی اش اینه که «کسی نمی تونه حافظه رو برای خودش برداره، سیستم عامل است که تقسیم می کنه بر اساس تشخیص خودش». اگر کسی دوست داشته این محدودیت رو به شکل موقت عوض کنه می زنه ulimit -l 1024 یا هر عدد دیگه و اگر بخواد برای همیشه اینو تغییر بده،‌ etc/security/limits.conf/ رو ادیت می کنه.

نکته: به جای عدد اگر بزنی 0 یعنی «نامحدود»

و اینطوریه که آدم از بودن توی فروم ها چیز یاد می گیره و این جزو خوبی های لینوکسه که کشف جواب ها واقعا سواد آدم رو زیاد می کنه. چیزی که با نصب دوباره و غیره اتفاق نمی افته.

  • لینوکس پر از این کانفیگ فایل های متنی هست و به نظرم همین یکی از ادمین پسند ترین قابلیت هاش باشه.
    کلا جنگولک بازی های زیادی میشه دراورد، برای یه پروژه ی جاج از چند تا از این قابلیت ها استفاده کردیم، مثل limits.conf، chroot.conf، و pam ها.
    خلاصه ی اون پروژه رو اینجا نوشتم: http://algorithms.ir/~mahrud/blog/2011/08/project-hellijudge

  • korosh

    در مورد اینکه این امکان یک ایده دانشجویی بوده و اینکه شلوغش کردی و اینها باید بگم که اصلن اینطور نیست این امکان مال لینوکس نیست مال ویندوز هم نیست مال مک هم نیست بلکه یک از مسائل مطرح در حوزه سیستم عامل هست سال ها هم هست داره روش بحث میشه و کلی متود مثل LRU و بقیه براش ایجاد شده و هنوزم دارن روش کار می کنن

  • مهدی

    صد در صد باهات موافقم. از وقتی از سه سال پیش سویچ کردم به لینوکس هم برای برنامه نویسی هم کارهای روزمره قویترین احساسی که داشتم اینه که تو این جو و سیستم سوادم افزایش پیدا کرده. اون هم سواد بدرد بخور که تضمین شده تا سالها بخاطر آزادی این سیستم به درد من بخوره و هیچ کسی نتونه دورش بریزه. در حالی که تو سیستم های بسته سواد من با تصمیم صاحب اون سیستم می تونه به سطل زباله منتقل بشه و این اتفاقیه که برای سواد من از ویندوز افتاده، یعنی تقریبا همه تجربه هایی که تو ویندوز داشتم با اومدن به لینوکس به سطل زباله منتقل شد ولی بازم هر وقت جلوی ضرر رو بگیری منفعته و بنابراین خوشحالم!

  • یه مساله‌ی بی‌ربط که نمی‌تونم جلوی خودم رو بگیرم و نگم! :)
    ۸ گیگ swapی که درست کردی با وجود ۸ گیگ رم هدر دادن فضای هارد دیسک نیست؟ من با ۱ گیگ رم، ۲ گیگ swap گذاشتم ولی تا حالا ندیدم حتی ۱ گیگش هم استفاده بشه. تو با وجود ۸ گیگ رم اصلا نیازی به swap نداری (طبق ویکی آرچ معمولا نیازی به استفاده از swap برای رم‌های بالاتر از ۱ گیگ نیست ‫[۱]) ضمن اینکه توصیه می‌شه فضای swap رو بیشتر از ۲ گیگ نذارن، چون استفاده نمی‌شه دیگه اونقدر!
    البته الان میای جواب می‌دی که برای hibernation نیاز به ۸ گیگ swap دارم و من ضایع می‌شم ولیکن نمی‌تونستم نگم دیگه! :دی

    [۱]- https://wiki.archlinux.org/index.php/Swap

    • جادی

      سوئپ من الان هیچ وقت مصرف نمی شه مگر اینکه کار خاصی بکنم. البته همونطورکه گفتی ساسپند به دیسک سوئپ لازم داره ولی اونم من تقریباهیچ وقت نمی کنم. مصرف رم شدیدا بستگی به زندگی آدم داره. مثلا من با این رم بیش از حد زیاد دو گیگ رم می دم به ماشین مجازی ام که کارهای شرکت توشه. ولی کماکان بودن سوئپ به نظرم برای شرایط خاص خوبه.

      مقدار سوئپ رو هم که از قدیم می گفتن دوبرابر رم ولی نه بیشتر از چهارگیگ چون اگر قرار باشه سیستم موقع کار واقعا بیشتر از چهار گیگ رو از دیسک بخونه و به عنوان رم قالب کنه احتمالا برنامه خیلی خیلی کند می شه. ولی خب من گذاشتم هشت دیگه (: دفاع منطقی ازش نمی کنم. فقط همینطوری.

      در مورد ویکی آرچ هم خب اشتباهه. حداقلش اینه که قدیمی است. من نگاه کردم. سال ۲۰۱۰ این بخش اضافه شده. الان یک گیگ رم واقعا کافی نیست و حتما کش می خواد. تو همون تصویر می بینی که کش استفاده شده من صفره (نگاه نکردم الان ولی حتما هست)‌ این یعنی هیچ وقت سراغ کش نرفتم. این عدد مهمیه همونطور که خودت هم گفتی و مال خودت رو هم نگاه کردی.

      حرف هات در کل درست بود و منم توضیح بیشتر اضافه کردم برای آیندگان (:

  • ساسان
    • جادی

      بله بله ساسان (: خب به همین دلیله که اینها رو می نویسم دیگه.

  • خودم

    تست