JavaRush /وبلاگ جاوا /Random-FA /چرخه زندگی شی

چرخه زندگی شی

در گروه منتشر شد
سلام! فکر می کنم زیاد تعجب نخواهید کرد اگر به شما بگوییم که حجم حافظه رایانه شما محدود است :) حتی یک هارد دیسک که چندین برابر بزرگتر از RAM است، می تواند با بازی های مورد علاقه شما، سریال های تلویزیونی، پر شود. و غیره برای جلوگیری از این اتفاق، باید وضعیت فعلی حافظه را کنترل کرده و فایل های غیر ضروری را از رایانه خود حذف کنید. برنامه نویسی جاوا چه ربطی به همه اینها دارد؟ مستقیم! از این گذشته، هنگامی که هر شیئی توسط ماشین جاوا ایجاد می شود، حافظه برای آن اختصاص می یابد. در یک برنامه بزرگ واقعی، ده‌ها و صدها هزار شی ایجاد می‌شود که هر کدام حافظه اختصاصی خود را دارند. چرخه زندگی شی - 1اما به نظر شما تا چه زمانی همه این اشیاء وجود دارند؟ آیا آنها در تمام مدتی که برنامه ما در حال اجرا است «زنده می‌شوند»؟ البته که نه. با تمام مزیت های آبجکت های جاوا، جاودانه نیستند :) اشیا چرخه زندگی خود را دارند. امروز کمی از نوشتن کد استراحت می‌کنیم و به این فرآیند نگاه می‌کنیم :) علاوه بر این، برای درک عملکرد برنامه و مدیریت منابع بسیار مهم است. بنابراین، زندگی یک شی از کجا شروع می شود؟ مانند شخص - از بدو تولد، یعنی خلقت.
Cat cat = new Cat();//вот сейчас и начался vital цикл нашего an object Cat!
ابتدا ماشین مجازی جاوا مقدار لازم حافظه را برای ایجاد شی اختصاص می دهد. سپس او پیوندی به آن ایجاد می کند، در مورد ما - catتا بتواند آن را ردیابی کند. پس از این، همه متغیرها مقداردهی اولیه می شوند، سازنده فراخوانی می شود، و ببینید، شی تازه ما در حال حاضر زندگی خود را دارد :) طول عمر اشیا متفاوت است، در اینجا اعداد دقیقی وجود ندارد. در هر صورت، برای مدتی در داخل برنامه زندگی می کند و وظایف خود را انجام می دهد. به‌طور دقیق، یک شی «زنده» است تا زمانی که اشاره‌هایی به آن وجود داشته باشد. به محض اینکه هیچ پیوندی باقی نماند، شی "می میرد". مثلا:
public class Car {

   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");
       lamborghini = null;

   }

}
در این روش، main()شیء ماشین لامبورگینی دیابلو از قبل در خط دوم زنده نیست. فقط یک پیوند به آن وجود داشت و اکنون این پیوند اختصاص داده شده است null. از آنجایی که هیچ مرجعی به لامبورگینی دیابلو باقی نمانده است، به "آشغال" تبدیل می شود. نیازی به تنظیم مجدد لینک نیست:
public class Car {

   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");

       Car lamborghiniGallardo = new Car("Lamborghini Gallardo");
       lamborghini = lamborghiniGallardo;
   }

}
در اینجا یک شیء دوم ایجاد کردیم، پس از آن مرجع را گرفتیم lamborghiniو آن را به این شی جدید اختصاص دادیم. اکنون Lamborghini Gallardoدو مرجع وجود دارد که به شی اشاره می کنند، اما Lamborghini Diabloهیچ مرجعی به شی وجود ندارد. بنابراین شیء Diabloتبدیل به زباله می شود. و در این لحظه مکانیزم جاوای داخلی به نام زباله جمع کن یا به عبارتی Garbage Collector GC وارد عمل می شود.
چرخه زندگی شی - 2
زباله جمع کن یک مکانیسم داخلی جاوا است که وظیفه آزادسازی حافظه، یعنی حذف اشیاء غیر ضروری از آن را بر عهده دارد. بیهوده نبود که تصویری را با جاروبرقی روباتی برای به تصویر کشیدن آن انتخاب کردیم. از این گذشته ، جمع کننده زباله تقریباً به همان روش کار می کند: در پس زمینه ، در برنامه شما "سفر می کند" ، زباله ها را جمع آوری می کند و در عین حال شما عملاً با آن تعامل ندارید. وظیفه آن حذف اشیایی است که دیگر در برنامه استفاده نمی شوند. بنابراین، حافظه موجود در رایانه را برای اشیاء دیگر آزاد می کند. یادتان هست در ابتدای سخنرانی گفتیم که در زندگی معمولی باید وضعیت رایانه خود را کنترل کنید و فایل های قدیمی را حذف کنید؟ بنابراین، در مورد اشیاء جاوا، زباله جمع کننده این کار را برای شما انجام می دهد. Garbage Collector بارها در طول اجرای برنامه شما راه اندازی می شود: نیازی به فراخوانی خاص و دستور دادن ندارد، اگرچه از نظر فنی این امکان وجود دارد. بعداً در مورد آن بیشتر صحبت خواهیم کرد و روند کار آن را با جزئیات بیشتری تحلیل خواهیم کرد. در لحظه ای که زباله جمع کن به جسم می رسد، درست قبل از تخریب آن، یک روش خاص بر روی شی فراخوانی می شود - finalize(). می توان از آن برای آزاد کردن برخی از منابع اضافی که شی استفاده می کرد استفاده کرد. متد finalize()متعلق به کلاس است Object. یعنی، همراه با و equals()، که قبلاً با آن آشنا شدید، هر شیئی آن را دارد. تفاوت آن با روش های دیگر این است که ... چگونه آن را ... بسیار دمدمی مزاج است. یعنی همیشه قبل از تخریب یک شیء فراخوانی نمی شود. برنامه نویسی یک چیز دقیق است. برنامه نویس به کامپیوتر می گوید کاری را انجام دهد و کامپیوتر آن را انجام می دهد. احتمالاً قبلاً به این رفتار عادت کرده‌اید، و ممکن است در ابتدا پذیرش این ایده برای شما دشوار باشد: «قبل از نابودی اشیا، متد کلاس نامیده می‌شود . یا نامیده نمی شود. اگر شانس بیاوریم!" با این حال، این درست است. خود ماشین جاوا تعیین می کند که آیا متد را در هر مورد خاص فراخوانی کند یا خیر. به عنوان مثال، بیایید سعی کنیم کد زیر را برای آزمایش اجرا کنیم: hashCode()toString()finalize()Objectfinalize()
public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public Cat() {
   }

   public static void main(String[] args) throws Throwable {

       for (int i = 0 ; i < 1000000; i++) {

           Cat cat = new Cat();
           cat = null;//вот здесь первый an object становится доступен сборщику мусора
       }
   }

   @Override
   protected void finalize() throws Throwable {
       System.out.println("Объект Cat уничтожен!");
   }
}
یک شی ایجاد می کنیم Catو در خط بعدی کد تنها مرجع به آن را ریست می کنیم. و بنابراین - یک میلیون بار. ما صراحتاً این روش را لغو کرده‌ایم finalize()، و باید هر بار قبل از نابود کردن شی، رشته را میلیون‌ها بار در کنسول چاپ کند Cat. اما نه! دقیق تر، فقط 37346 بار روی کامپیوتر من اجرا شد! یعنی فقط در 1 مورد از 27 مورد، دستگاه جاوا که من نصب کردم تصمیم به فراخوانی یک روش گرفت finalize()- در موارد دیگر، جمع آوری زباله بدون این کار انجام شد. خودتان این کد را اجرا کنید: به احتمال زیاد، نتیجه متفاوت خواهد بود. همانطور که می بینید، سخت است که آن را یک شریک قابل اعتماد نامید :) بنابراین، یک توصیه کوچک برای آینده: در مورد آزاد کردن برخی از منابع حیاتی، finalize()نباید به روش تکیه کنید . finalize()شاید JVM آن را صدا کند، شاید هم نه. چه کسی می داند؟ اگر شیء شما در طول عمر خود منابعی را اشغال می کرد که برای عملکرد بسیار مهم بودند، مثلاً یک اتصال باز به پایگاه داده نگه می داشت، بهتر است یک متد خاص در کلاس خود ایجاد کنید تا آنها را آزاد کنید و زمانی که شیء به طور واضح آن را فراخوانی کنید. دیگر مورد نیاز نیست به این ترتیب مطمئناً متوجه خواهید شد که عملکرد برنامه شما آسیب نخواهد دید. در همان ابتدا گفتیم که مدیریت حافظه و حذف زباله بسیار مهم است و این درست است. مدیریت نامناسب منابع و عدم درک فرآیند مونتاژ اشیاء غیر ضروری می تواند منجر به نشت حافظه شود. این یکی از معروف ترین اشتباهات برنامه نویسی است. کد نوشته شده نادرست توسط برنامه نویس می تواند منجر به تخصیص حافظه جدید در هر بار برای اشیاء تازه ایجاد شده شود، در حالی که اشیاء قدیمی و غیر ضروری برای حذف توسط جمع کننده زباله در دسترس نیستند. از آنجایی که ما با یک ربات جاروبرقی قیاس کردیم، تصور کنید چه اتفاقی می‌افتد اگر قبل از راه‌اندازی ربات، جوراب‌هایی را در اطراف خانه پراکنده کنید، یک گلدان شیشه‌ای را بشکنید و یک مجموعه لگو جدا شده را روی زمین بگذارید. ربات، البته، سعی می کند کاری انجام دهد، اما در یک نقطه گیر می کند.
چرخه زندگی شی - 3
برای اینکه جاروبرقی به درستی کار کند، باید کف را در شرایط خوبی نگه دارید و هر چیزی را که جاروبرقی قادر به تحمل آن نیست از آنجا جدا کنید. زباله جمع کن بر همین اصل کار می کند. اگر اشیاء زیادی در برنامه باقی مانده باشد که نتواند آنها را جمع کند (مانند جوراب یا لگو برای جاروبرقی روباتی)، در یک نقطه حافظه تمام می شود. و نه تنها برنامه ای که نوشتید، بلکه همه برنامه های دیگری که در آن لحظه روی رایانه اجرا می شوند نیز مسدود می شود. حافظه کافی برای آنها نیز وجود نخواهد داشت. چرخه حیات شی و جمع‌آورنده زباله در جاوا به این شکل است. نیازی به حفظ کردن این نیست: فقط اصل کار را درک کنید. در سخنرانی بعدی در مورد این فرآیندها با جزئیات بیشتری صحبت خواهیم کرد، اما در حال حاضر می توانید به حل مشکلات JavaRush بازگردید :) موفق باشید!
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION