CodeGym /Java блог /Случаен /Жизнен цикъл на обекта
John Squirrels
Ниво
San Francisco

Жизнен цикъл на обекта

Публикувано в групата
здрасти Мисля, че няма да се изненадате много, ако ви кажа, че компютърът ви има ограничено количество памет :)
Жизнен цикъл на обекта - 1
Дори вашият твърд диск (който е много, много пъти по-голям от RAM) може да се напълни с любимите ви игри, телевизионни предавания и други неща. За да предотвратите това, трябва да наблюдавате текущото състояние на паметта на вашия компютър и да изтриете ненужните файлове. Как всичко това е свързано с програмирането на Java? Съвсем директно! В края на краищата, създаването на който и да е обект кара Java машината да отдели памет за него . Една голяма програма от реалния свят създава десетки or стотици хиляди обекти и за всеки от тях се разпределя част от паметта. Но Howво мислите, колко от тези обекти съществуват? „Живи“ ли са през цялото време, докато програмата ни работи? Разбира се, че не. Дори и с всичките си предимства, Java обектите не са безсмъртни :) Обектите имат свой собствен жизнен цикъл. Днес ще си вземем малка почивка от писането на code и ще проучим този процес :) Освен това е много важен за разбирането How работи една програма и за управлението на ресурсите. И така, откъде започва животът на един обект? Като човек, от раждането си, т.е. когато е създаден.

Cat cat = new Cat();// Our Cat object's lifecycle begins now!
Първо, виртуалната машина на Java разпределя паметта, необходима за създаване на обекта. След това създава препратка към него (в нашия случай, 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()метода обектът "Lamborghini Diablo" Car престава да бъде жив на втория ред. Имаше само една препратка към него и препратката беше зададена на нула. Тъй като няма останали препратки към Diablo, той става "боклук". Референцията не трябва да бъде зададена на нула, за да се случи това:

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обектът се превръща в боклук. Това е моментът, когато вграденият събирач на боклук (GC) на Java се включва.
Жизнен цикъл на обекта - 2
Събирачът на отпадъци е вътрешен механизъм на Java, отговорен за освобождаване на памет, т.е. премахване на ненужни обекти от паметта. Има причина, поради която избрахме да го представим с прахосмукачка робот. Събирачът на боклук работи приблизително по същия начин: той се "движи" във вашата програма във фонов режим, събирайки боклука. На практика не е нужно да взаимодействате с него. Неговата задача е да изтрива обекти, които вече не се използват в програмата. По този начин се освобождава памет за други обекти. Спомняте ли си, че в началото на урока казахме, че в реалния живот трябва да наблюдавате състоянието на компютъра си и да изтривате стари файлове? Ако говорим за Java обекти, събирачът на отпадъци прави това instead of вас. Събирачът на отпадъци се стартира много пъти, докато вашата програма работи: не е необходимо изрично да го извиквате и да му давате команди (въпреки че това е технически възможно). По-късно ще говорим повече за събирача на отпадъци и ще анализираме How работи по-подробно. Когато събирачът на боклук достигне обект - точно преди да бъде унищожен - finalize()се извиква специалният метод на обекта. Този метод може да бъде извикан за освобождаване на определени допълнителни ресурси, използвани от обекта. Методът finalize()принадлежи към класа Object. С други думи, това е подобно на equals()и hashCode()( toString()което сте срещали преди). Всеки предмет го има . Различава се от другите методи по това...How да го кажем...много е умишлено. С това имаме предвид товане винаги се извиква преди даден обект да бъде унищожен . Програмирането е много прецизна дейност. Програмистът казва на компютъра да направи нещо и компютърът го прави. Предполагам, че сте свикнали с този вид поведение, така че в началото може да ви е трудно да приемете следната идея: „Преди обектът да бъде унищожен, се извиква методът на класа Object. Или не. finalize()Ако имаме късмет! " Все пак това е реалността. Java машината сама определя дали да извика finalize() за всеки отделен случай. Като експеримент, нека опитаме да изпълним следния code:

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;// The first object becomes available for garbage collection here
       }
   }

   @Override
   protected void finalize() throws Throwable {
       System.out.println("The Cat is destroyed!");
   }
}
Създаваме Catобект и в следващия ред нулираме единствената препратка към него. И ние го правим мorони пъти. Ние изрично отменихме finalize()метода. Всеки път, когато даден Catобект бъде унищожен, той трябва да покаже низ - общо един мorон пъти. Но не! За да бъда точен, на моя компютър беше изпълнен само 37346 пъти! С други думи, моята Java машина реши да извика finalize()метода само в 1 от всеки 27 случая. В останалите случаи събирането на боклука не включва това повикване. Опитайте сами да стартирате този code. Най-вероятно ще получите различен резултат. Както можете да видите, трудно е да се нарече finalize()надежден партньор :) Така че, ето малък съвет за бъдещето: не разчитайте на finalize()метода за освобождаване на критични ресурси.JVM може да го извика, а може и да не. Кой знае? Ако вашият обект съдържа някои критични за производителността ресурси (например връзка с отворена база данни), докато е бил активен, би било по-добре да създадете и изрично да извикате специален метод за освобождаването им, когато обектът вече не е необходим. По този начин ще знаете със сигурност, че производителността на вашата програма няма да пострада. Започнахме, като казахме, че работата с паметта и събирането на отпадъци са много важни теми и наистина са. Лошото боequalsе с ресурси и неразбирането How се почистват ненужните обекти може да доведе до един от най-неприятните грешки: изтичане на памет . Това е една от най-известните програмни грешки. Дори има собствена статия в Уикипедия. Лошо написаният code може да създаде ситуация, при която паметта се разпределя всеки път за новосъздадени обекти, но старите, ненужни обекти не са достъпни за събиране на боклук. Тъй като вече направихме аналогия с прахосмукачката-робот, представете си Howво би се случило, ако преди да пуснете робота разпръснете чорапи из цялата къща, разбиете стъклена ваза и оставите парчета Лего по пода. Естествено, роботът ще се опита да направи нещо, но един ден ще се сграбчи.
Жизнен цикъл на обекта - 3
За да работи прахосмукачката правилно, трябва да поддържате пода в прorчна форма и да събирате всичко, с което не може да се справи. Събирачът на отпадъци следва същия принцип. Ако една програма има много обекти, които не може да почисти (като чорап or Лего за нашата роботизирана прахосмукачка), един ден паметта ни ще свърши. Не само вашата програма ще виси, но и всички други програми, които случайно се изпълняват на компютъра. В крайна сметка и паметта няма да им стигне (да се върнем към нашата аналогия, счупеното стъкло на пода спира не само прахосмукачката, но и хората, които живеят в дома). Накратко, така изглеждат жизненият цикъл на обекта и събирането на боклука в Java. Не е необходимо да запомняте това: достатъчно е просто да разберете How работи. В следващия урок ние ще се върна към тези процеси по-подробно. Но засега можете да се върнете към решаването на задачи на CodeGym :) Успех!
Коментари
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION