در ابتدا yourkit را از سایت خود آن دانلود کردیم و در ویندوز به سادگی نصب کردیم. در مرحله بعد طبق دستورات فایل آزمایش با موفقیت توانستیم افزونه مربوطه را به Intellij اضافه کنیم .
آیکون yourkit در صفحه اجرا قرار گرفت.
در مرحله بعدی پروژه قرارداده شده را دانلود کردیم و آن را توسط Intellij باز کردیم. سپس با استفاده از آیکون اضافه شده در مرحله قبلی از آن run گرفتیم : و نتیجه را در محیط گرافیکی نرم افزار نصب شده yourkit مشاهده کردیم :
همانطور که در عکس بالا مشخص است بیشترین مصرف cpu در تابع temp است که 98درصد cpu را به خود اختصاص داده.
وارد قسمت memory شده و در آنجا مصارف زیر را مشاهده کردیم :
که در آن چندین مورد مشخص است .
مورد اول درگیر شدن بیش از 3 گیگابایت memory در حالت total است که کمی عجیب بود. برای همین با تسک منیجر هم یک بار ران کردیم تا از صحت اطلاعات داده شده توسط پروفایلر مطمئن شویم :
که دقیقا مورد بالا را تایید می کرد. با توجه به عکس قبلی به تابع هایی که مصرف آنها بالا بود توجه کردیم و علت را متوجه شدیم:
که به اینصورت عمل می کند : هر بار چیزی به آن اضافه میشود اگر نزدیک به پر شدن باشد حافظه خود را دو برابر می کند (یک لیست جدید به طرفیت دو برابر ایجاد کرده و قبلی ها را کپی می کند) .
پس برای اصلاح این مورد از تکه کد زیر به جای temp استفاده کردیم :
public static void temp() {
int [][] a = new int[10000][20000];
for (int i = 0; i < 10000; i++)
{
for (int j = 0; j < 20000; j++) {
a[i][j] = i + j;
}
}
}
یک آرایه دوبعدی برای ذخیره کردن آن اعداد مورد نظر با ظرفیت اولیه مشخص تعریف کردیم و ادامه دادیم.
حاصل بعد از ران کردن به صورت زیر بود :
که همانطور که مشاهده می شود زمان درگیری cpu حدود 1/10 برابر شده، میزان مصرف تابع temp به 77 درصد کاهش یافته و در حوزه memory در بیشترین حالت چیزی حدود 110 مگابایت مصرف داشتیم. که نشان دهنده کاهش به میزان حدودا 1/30 است!
کدی که نوشتیم به این صورت بود که ابتدا یک عدد از کاربر دریافت می کرد و سپس فاکتوریل تمام اعداد یک تا آن عدد را نشان می داد. منتهی در این بین بین نشان دادن هر عدد برای اینکه خواننده ببیند نیاز بود که کمی delay داشته باشیم.
در مرحله اول کدی مانند کد قبل برای ایجاد delay نوشته شد.
private static void delay() {
int [][] arr = new int[10000][10000];
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < 10000; j++) {
for (int k = 0; k < 100; k++) {
arr[i][j] = i * j + k ;
}
}
}
}
که نتایج آن در عکس های زیر بعد از profiling مشخص است :
که تاخیر زیاد مهم نیست زیرا دست خودمان است که چقدر آن را ست کنیم و بسته به نیاز ما جلو می رود. اما ایرادی که این روش دارد این است که حافظه نسبتا زیادی فقط برای این اکشن کوچک در نظر می گیرد و حدود 500 مگابایت مصرف می کند.
حال کد را به صورت زیر تغییر دادیم :
private static void delay() {
Random rand = new Random();
for (int i = 0; i < 100000000; i++) {
int b = rand.nextInt();
}
}
که باعث خروجی های زیر شد :
که باز میزان درگیری cpu به علت زمان که همان delay است زیاد مهم نیست ولی موضوع مهم در حوزه memory هست که کلا 14 مگابایت آن هم از فضای غیرهیپ اشغال کرده که نشان دهنده برتری از نظر فضا برای این روش دارد.
نتیجه ای که از این مسائل بدست آمد این است که خیلی جاها ممکن است ما حواسمان به یکسری موضوعات نباشد که به سادگی می توانند باعث تاخیر و مصرف memory شوند. مانند استفاده از یک سری از لیست ها به جای آرایه
در نهایت به کمک profiling می توانیم نقاطی که فشار زیادی به منابع ما می آورند را شناسایی کرده و برای رفع و بهبود انها تلاش کنیم