JavaRush /Java Blogu /Random-AZ /Obyektin həyat dövrü

Obyektin həyat dövrü

Qrupda dərc edilmişdir
Salam! Düşünürəm ki, kompüterinizdə yaddaşın həcmi məhduddur desək, çox da təəccüblənməzsiniz :) RAM-dən qat-qat böyük olan sərt disk belə sevdiyiniz oyunlar, seriallar, və s. Bunun baş verməməsi üçün yaddaşın cari vəziyyətini izləmək və lazımsız faylları kompüterinizdən silmək lazımdır. Java proqramlaşdırmasının bütün bunlarla nə əlaqəsi var? Birbaşa! Axı Java maşını tərəfindən hər hansı obyekt yaradılanda onun üçün yaddaş ayrılır. Həqiqi böyük proqramda on və yüz minlərlə obyekt yaradılır ki, onların hər birinin özünəməxsus yaddaşı ayrılır. Obyektin həyat dövrü - 1Bəs sizcə, bütün bu obyektlər nə vaxta qədər mövcuddur? Proqramımızın işlədiyi bütün vaxtı "yaşayırlar"? Təbii ki, yox. Java obyektlərinin bütün üstünlükləri ilə onlar ölməz deyillər :) Obyektlərin öz həyat dövrü var. Bu gün kod yazmağa bir az ara verəcəyik və bu prosesə baxacağıq :) Üstəlik, proqramın işini başa düşmək və resursları idarə etmək üçün çox vacibdir. Beləliklə, bir obyektin həyatı haradan başlayır? İnsan kimi - doğulduğundan, yəni yaradılışından.
Cat cat = new Cat();//вот сейчас и начался vital цикл нашего an object Cat!
Birincisi, Java Virtual Maşın obyekti yaratmaq üçün lazımi yaddaş həcmini ayırır. Sonra o, ona bir keçid yaradır, bizim vəziyyətimizdə - catonu izləyə bilmək üçün. Bundan sonra bütün dəyişənlər inisiallaşdırılır, konstruktor çağırılır və bax, bizim təzə obyektimiz artıq öz həyatını yaşayır :) Obyektlərin ömrü fərqlidir, burada dəqiq rəqəmlər yoxdur. Hər halda, bir müddət proqramın daxilində yaşayır və öz funksiyalarını yerinə yetirir. Dəqiq desək, obyektə istinadlar olduğu müddətcə “canlıdır”. Heç bir əlaqə qalmayan kimi obyekt "ölür". Misal üçün:
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;

   }

}
Metodda main()Lamborghini Diablo avtomobil obyekti artıq ikinci cərgədə canlı olmağı dayandırır. Ona yalnız bir keçid var idi və indi bu keçid təyin edildi null. Lamborghini Diablo-ya heç bir istinad qalmadığından, o, "zibil" olur. Linki sıfırlamaq lazım deyil:
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;
   }

}
Burada biz ikinci obyekt yaratdıq, ondan sonra istinadı götürüb lamborghinibu yeni obyektə təyin etdik. İndi Lamborghini Gallardoobyektə işarə edən iki istinad var, lakin Lamborghini Diabloobyektə heç biri. Beləliklə, obyekt Diablozibil olur. Və bu anda, zibil toplayıcı və ya başqa sözlə - Garbage Collector, GC adlanan daxili Java mexanizmi işə düşür.
Obyektin həyat dövrü - 2
Zibil toplayıcı yaddaşın boşaldılmasına, yəni ondan lazımsız obyektlərin çıxarılmasına cavabdeh olan daxili Java mexanizmidir. Onu təsvir etmək üçün robot tozsoranla şəkil seçməyimiz əbəs yerə deyildi. Axı, zibil yığan eyni şəkildə işləyir: arxa planda o, proqramınız vasitəsilə "səyahət edir", zibil toplayır və eyni zamanda siz onunla praktiki olaraq əlaqə saxlamırsınız. Onun işi proqramda artıq istifadə olunmayan obyektləri silməkdir. Beləliklə, kompüterdəki yaddaşı digər obyektlər üçün boşaldır. Yadınızdadırmı, mühazirənin əvvəlində demişdik ki, adi həyatda kompüterinizin vəziyyətinə nəzarət etməli və köhnə faylları silməlisiniz? Beləliklə, Java obyektləri vəziyyətində, zibil toplayıcı bunu sizin üçün edir. Garbage Collector proqramınızın işləməsi zamanı dəfələrlə işə salınır: texniki cəhətdən mümkün olsa da, onu xüsusi olaraq çağırmaq və əmrlər vermək lazım deyil. Daha sonra bu barədə daha çox danışacağıq və onun iş prosesini daha ətraflı təhlil edəcəyik. Zibilyığan obyektə çatdığı anda, onun məhv edilməsindən bir qədər əvvəl, obyektə xüsusi bir üsul çağırılır - finalize(). O, obyektin istifadə etdiyi bəzi əlavə resursları boşaltmaq üçün istifadə edilə bilər. Metod finalize()sinifə aiddir Object. Yəni əvvəllər tanış olduğunuz equals(), hashCode()və ilə birlikdə hər hansı bir obyektdə ona malikdir. toString()Onun digər üsullardan fərqi odur ki... necə desək... çox şıltaqdır. Yəni, bir obyekti məhv etməzdən əvvəl həmişə çağırılmır. Proqramlaşdırma dəqiq bir şeydir. Proqramçı kompüterə bir şey etməyi əmr edir və kompüter bunu edir. Yəqin ki, siz artıq bu davranışa öyrəşmisiniz və ilk anda bu fikri qəbul etmək sizin üçün çətin ola bilər: “Obyektlər məhv edilməzdən əvvəl sinif finalize()metodu Object. Ya da deyilmir. Bəxtimiz gətirsə!" Bununla belə, bu doğrudur. finalize()Java maşını özü hər bir konkret halda metodu çağırıb çağırmamağı müəyyən edir . Məsələn, təcrübə üçün aşağıdakı kodu işə salmağa çalışaq:
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 уничтожен!");
   }
}
Biz bir obyekt yaradırıq Catvə kodun növbəti sətirində ona yeganə istinadı sıfırlayırıq. Və beləliklə - milyon dəfə. Biz metodu açıq şəkildə ləğv etdik finalize()və o, hər dəfə obyekti məhv etməzdən əvvəl sətri konsolda milyon dəfə çap etməlidir Cat. Amma yox! Dəqiq desəm, o, mənim kompüterimdə cəmi 37,346 dəfə işlədi! Yəni, 27-dən yalnız 1-də quraşdırdığım Java maşını metodu çağırmaq qərarına gəldi finalize()- digər hallarda zibil yığımı bu olmadan davam etdi. Bu kodu özünüz işə salın: çox güman ki, nəticə fərqli olacaq. Gördüyünüz kimi, onu etibarlı tərəfdaş adlandırmaq çətindir :) Buna görə də, gələcək üçün kiçik bir məsləhət: bəzi kritik resursların boşaldılması vəziyyətində finalize()metoda etibar etməməlisiniz . finalize()Bəlkə JVM bunu çağıracaq, bəlkə də yox. Kim bilir? Əgər fəaliyyət göstərdiyi müddətdə obyektiniz performans üçün çox vacib olan bəzi resursları tuturdusa, məsələn, verilənlər bazası ilə açıq əlaqə saxlayırsa, onları azad etmək üçün sinifinizdə xüsusi bir metod yaratmaq və obyekt açıq olduqda onu çağırmaq daha yaxşıdır. artıq lazım deyil. Beləliklə, proqramınızın performansının zərər görməyəcəyinə əmin olacaqsınız. Əvvəlcə dedik ki, yaddaşın idarə edilməsi və zibilin çıxarılması çox vacibdir və bu, doğrudur. Resurslarla düzgün işləmək və lazımsız obyektlərin yığılması prosesini başa düşməmək yaddaşın sızmasına səbəb ola bilər. Bu, ən məşhur proqramlaşdırma səhvlərindən biridir. Proqramçı tərəfindən səhv yazılmış kod hər dəfə yeni yaradılmış obyektlər üçün yeni yaddaşın ayrılması ilə nəticələnə bilər, köhnə, lazımsız obyektlər isə zibil yığan tərəfindən çıxarıla bilməz. Robot tozsoranla bənzətmə apardığımız üçün təsəvvür edin ki, robotu işə salmazdan əvvəl evin ətrafına corab səpsəniz, şüşə vazanı sındırsanız və yerə sökülmüş Leqo dəstini qoysanız nə baş verərdi. Robot, əlbəttə ki, bir şey etməyə çalışacaq, lakin bir anda ilişib qalacaq.
Obyektin həyat dövrü - 3
Düzgün işləməsi üçün döşəməni yaxşı vəziyyətdə saxlamalı və tozsoranın idarə edə bilməyəcəyi hər şeyi oradan çıxarmalısınız. Zibil yığan maşın eyni prinsiplə işləyir. Proqramda toplaya bilməyəcəyi çoxlu obyekt qalsa (məsələn, robot tozsoran üçün corab və ya Lego), bir anda yaddaş tükənəcək. Və təkcə yazdığınız proqram deyil, o anda kompüterdə işləyən bütün digər proqramlar da donacaq. Onlar üçün də kifayət qədər yaddaş olmayacaq. Java-da obyektin həyat dövrü və zibil toplayıcısı belə görünür. Bunu yadda saxlamağa ehtiyac yoxdur: sadəcə iş prinsipini başa düş. Növbəti mühazirədə bu proseslər haqqında daha ətraflı danışacağıq, lakin hələlik JavaRush problemlərinin həllinə qayıda bilərsiniz :) Uğurlar!
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION