استارت‌آپ و کارآفرینی

کد PHP من چقدر از حافظه را اشغال می کند؟

هر پروسسی که در سیستم عامل اجرا می‌شود مقداری از حافظه را اشغال می‌کند. حافظه شامل بایت‌ها، پشته (stack)، هیپ (heap) و … است. بگذارید کمی وارد حوزه برنامه نویسی PHP شویم. همانطور که می‌دانید زیر بنای PHP، زبان C است. در C هر تابعی که فراخوانی می‌شود یک پشته را اشغال می‌کند و در PHP چند پشته اشغال می‌شود. ( حتما می دانید چرا!!)

نتیجه:  اگر تابعی در هسته PHP موجود است دوباره آن را در PHP بازنویسی نکنید.

کدهایی که می‌نویسیم اگر بهینه نباشند شاید در پروژه‌های کوچک خود را نشان ندهند، اما وقتی پروژه در حدی است که کاربران زیادی اسکریپت شما را فراخوانی می‌کنند باید کمی نگران بود. وقتی متغیری تعریف می‌کنید یعنی حافظه مصرف کردید. وقتی تابعی فراخوانی می‌شود پشته مصرف می‌کند. البته PHP در کنترل متغیرها خوب عمل می‌کند. اما در بعضی مواقع برنامه نویس می‌تواند اوضاع را خراب کند.

به مثال زیر دقت کنید:

$a = str_repeat('x', 100000000); // Memory used ~ 100 MB
$b = $a;                         // Memory used ~ 100 MB
$b = $b . 'x';                   // Memory used ~ 200 MB

php از الگوی (Copy on Write (COW استفاده می‌کند. یعنی تا موقعی که مقدار یک متغیر تغییر نکند فضای جدیدی اشغال نخواهد شد. متغیر b$ را چون به a$ نسبت دادیم پس فضای جدید قابل ملاحظه ای را استفاده نکردیم. اما در خط سوم چون مقداری را در متغیر نوشتیم بنابراین مقدار متغیر a$ کپی شده و مقدار جدید به آن اضافه خواهد شد.

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

اکستنشن php-memory-profiler به شما کمک زیادی می کند. می توانید این اکستنشن را از pecl دریافت و نصب کنید.

 

نحوه نصب در لینوکس:

pecl install memprof

 

نمونه کد:

<?

memprof_enable();

a();

function a(){
    usleep(1000);
    if(++$GLOBALS['cycle1']<5){
        $GLOBALS['cycle2']=0;
        b();
        c();
    }
}

function b(){
    usleep(2000);
    if(++$GLOBALS['cycle2']<3){
        b();
    }
    $GLOBALS['mempad'].=str_repeat('x',1024*1024);
}

function c(){
    usleep(3000);
    $GLOBALS['mempad']='';
    a();
} 

$dump = memprof_dump_array();
echo '<pre>';print_r($dump);

?>

نمونه کد فوق آرایه ای از میزان فضای اختصاص داده شده به هر قسمت از کد شما را بر می‌گرداند. اما اگر می خواهید گرافی به شکل زیر ببینید کمی صبر کنید:

 

memprof

نمونه کد:

<?
$res = fopen("/tmp/callgrind.out", "w");
memprof_enable();

a();

function a(){
    usleep(1000);
    if(++$GLOBALS['cycle1']<5){
        $GLOBALS['cycle2']=0;
        b();
        c();
    }
}

function b(){
    usleep(2000);
    if(++$GLOBALS['cycle2']<3){
        b();
    }
    $GLOBALS['mempad'].=str_repeat('x',1024*1024);
}

function c(){
    usleep(3000);
    $GLOBALS['mempad']='';
    a();
} 

memprof_dump_callgrind($res);
    
?>

 

نمونه کد فوق میزان فضای اختصاص داده شده به کل کد شما و همچنین میزان فضای اختصاص یافته به توابع و دستورات شما را در فایلی به آدرس زیر ذخیره می کند:

/tmp/callgrind.out

این فایل به فرمت خاصی اطلاعات را ذخیره می کند که با نرم افزار KCachegrind می توانید آن را مشابه آنچه در تصویر فوق مشاهده کردید مشاهده کنید.

نصب در لینوکس:

sudo apt-get install kcachegrind

 

اگر فایل را با نرم افزار KCachegrind مشاهده کنید به شما گراف مموری اختصاص یافته به کدتان را نشان می دهد.

2 نظرات
  1. احسان می گوید

    سلام
    عالی بود!!
    شما برای شروع برنامه نویسی با php چه منبعی رو پیشنهاد می کنید؟

    1. علی ذوقی می گوید

      سلام
      خداروشکر
      داکیومنتهای انگلیسی موجود در اینترنت بهترین گزینه است.

      بنده کتاب ترجمه شده خوندن رو اصلا برای یادگیری توصیه نمیکنم.

ارسال یک پاسخ

آدرس ایمیل شما منتشر نخواهد شد.