CodeGym /Java блог /Случаен /Повече за събирача на отпадъци
John Squirrels
Ниво
San Francisco

Повече за събирача на отпадъци

Публикувано в групата
здрасти В последния урок за първи път се запознахме с вградения събирач на отпадъци в Java и получихме груба представа How работи. Работи във фонов режим, докато програмата ви работи, събирайки ненужни обекти, които ще бъдат изтрити по-късно. По този начин се освобождава памет, която може да се използва за създаване на нови обекти в бъдеще.
Повече за събирача на отпадъци - 1
В този урок ще обсъдим по-подробно How работи. Например, How и кога един предмет става ненужен? И How боклукчия разбира? Това са въпроси, на които ще отговорим по време на днешния урок :) Урокът ще бъде по-скоро като преглед: не е нужно да учите този материал наизуст. Намерението е основно да разширим визията ви за това How работят паметта и събирача на отпадъци, така че просто прочетете и намерете нещо ново за себе си :) Давай! Първото нещо, което трябва да запомните е, че събирачът на отпадъци работи паралелно с вашата програма. Не е част от вашата програма. Работи отделно (в последния урок сравнихме това с прахосмукачка робот). Но не винаги е било така. Събирането на боклука се извършваше в същата нишка като вашата програма. По няHowъв график (веднъж на всеки няколко minutesи) събирачът на боклук проверява за наличието на нежелани обекти в програмата. Проблемът беше, че програмата висеше (не се изпълняваше) по време на тази проверка и събиране на боклук. Представете си, че седите в офиса си на работа. Но тогава влиза чистачката да измие подовете. Тя те отдалечава от компютъра ти за 5 minutesи и чакаш, докато тя приключи с почистването. През това време не сте в състояние да работите. Приблизително така работеше събирането на боклук :) Този механизъм по-късно беше променен и сега събирачът на боклук работи във фонов режим, без да възпрепятства работата на самата програма. Вече знаете, че един обект умира, когато вече няма препратки. В действителност,събирачът на боклук не брои препратки към обекти . Първо, това може да отнеме много време. Второ, не е много ефективно. В крайна сметка обектите могат да се отнасят един към друг! Повече за събирача на боклук - 2Фигурата показва пример, при който 3 обекта се отнасят един към друг, но никой друг не се отнася към тях. С други думи, останалата част от програмата не се нуждае от тях. Ако събирачът на отпадъци просто преброи препратките, тези 3 обекта няма да бъдат събрани и паметта няма да бъде освободена (има препратки към тях!). Можем да сравним това с космически кораб. По време на полета астронавтите решават да проверят списъка с резервни части, налични за ремонт. Освен всичко друго, те намират волан и педали от обикновена кола. Очевидно те не са необходими тук и заемат излишно място (въпреки че тези две части са свързани една с друга и имат някои функции). Но вътре в космическия кораб те са безполезен боклук, който трябва да се изхвърли. Съответно, в Java беше взето решение да се събира боклук въз основа не на преброяване на препратки,достижими и недостижими . Как да определим дали даден обект е достъпен? Всичко е просто гениално. Един обект е достъпен, ако е посочен от друг достъпен обект. Така получаваме "верига на достижимост". Започва, когато програмата започне и продължава по време на програмата. Изглежда по следния начин: Повече за събирача на боклук - 3 Стрелката на фигурата показва изпълнимия code на нашата програма. Кодът (например методът main()) създава препратки към обекти. Тези обекти могат да препращат към други обекти, тези обекти към други и т.н. Това формира референтна верига. Ако можете да проследите по веригата от обект до "основната препратка" (тази, която е създадена директно в изпълним code), тогава тя се счита за достъпна. Такива обекти са маркирани с черно на снимката. Но обектът е недостижим, ако обектът изпадне от тази верига, т.е. никоя от променливите в codeа, който се изпълнява в момента, не го препраща и не може да бъде достигнат през "референтната верига". В нашата програма два такива обекта са отбелязани с червено. Имайте предвид, че тези "червени" обекти имат препратки един към друг. Но Howто казахме по-рано, модерният събирач на отпадъци на Java не брои препратки. Той определя дали даден обект е достъпен or недостижим. В резултат на това ще се хване за двата червени обекта на фигурата. Сега нека разгледаме целия процес от началото до края. По този начин ще видим също How паметта е подредена в Java :) Всички Java обекти се съхраняват в специална област от паметта, наречена heap . В ежедневния език купчината обикновено е планина от елементи, където всичко е смесено. Но това не е купчината в Java. Структурата му е много логична и разумна. В един момент Java програмистите откриха, че всички техни обекти могат да бъдат разделени на два типа: прости обекти и „дългоживеещи обекти“. „Дългоживеещи обекти“ са обекти, които са преживели много кръгове на събиране на боклука. Те обикновено живеят до края на програмата. В крайна сметка пълната купчина, където се съхраняват всички обекти, беше разделена на няколко части. Първата част има красиво име: eden(от библейската "Райска градина"). Това име е подходящо, защото това е мястото, където обектите завършват, след като са създадени. Това е частта от паметта, където се създават нови обекти, когато използваме ключовата дума new. Могат да бъдат създадени много обекти. Когато мястото в тази зона свърши, започва първоначално „бързо“ събиране на боклука. Трябва да кажем, че събирачът на боклук е много умен. Той избира алгоритъм въз основа на това дали купчината има повече боклук or повече живи обекти. Ако почти всички обекти са боклук, колекторът маркира живите обекти и ги премества в друга област на паметта. Тогава текущата област е напълно изчистена. Ако няма много боклук и купчината е предимно живи предмети, събирачът маркира боклука, изчиства го и опакова другите предмети заедно. Ние казахме "пространство за оцеляване . Пространството за оцеляване от своя страна е разделено на поколения . Всеки обект принадлежи на определено поколение в зависимост от това колко кръга на събиране на боклука е оцелял. Ако даден обект е оцелял след един цикъл на събиране на боклук, тогава той е в "Поколение 1"; ако 5, тогава "Поколение 5". Заедно, eden и пространството за оцеляване образуват област, наречена младото поколение . В допълнение към младото поколение, купчината има друга област на паметта, наречена старо поколение. Това е точно зоната, където се озовават дълголетни предмети, преживели многократно събиране на боклука. Има предимства да ги държите отделно от всички останали. Пълното събиране на отпадъци се извършва само когато старото поколение е пълно, т.е. има толкова много дългоживеещи обекти в програмата, че няма достатъчно памет. Този процес включва повече от една област на паметта. Като цяло включва всички обекти, създадени от Java машината. Естествено, това отнема много повече време и средства. Именно това е решението да се съхраняват дълготрайни предмети отделно. „Бързо събиране на боклука“ се извършва, когато в други зони липсва място. Това включва само една област, което го прави по-бързо и по-ефективно. Накрая, когато дори зоната за дълголетни обекти е напълно запълнена, задейства се пълно събиране на отпадъци. Така колекционерът използва "най-тежкия" инструмент само когато е невъзможно да го избегне. Ето визуално представяне на структурата на купчината и събирането на отпадъци: Повече за събирача на боклук - 4
Коментари
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION