"Здравей! Реших да ти дам още един малък урок за събирането на боклука."

Както вече знаете, Java машината сама следи, когато даден обект стане ненужен, и го изтрива.

"Да. Ти и Риши ми казахте за това по-рано. Не помня подробностите."

"ОК. Тогава нека го прегледаме отново."

Извозване на боклук - 1

"Веднага щом бъде създаден обект, JVM разпределя памет за него. Интересът към обекта се следи с помощта на референтни променливи.  Обект може да бъде изтрит по време на събиране на отпадъци, т.е. proceduresата, чрез която се освобождава памет, ако няма променливи, препращащи към обект. "

„Разкажете ми малко за събирача на отпадъци – Howво е това и How работи.“

"ОК. Събирането на боклука се случваше в главната нишка. На всеки 5 minutesи or по-често. Ако някога нямаше достатъчно свободна памет, Java машината спираше всички нишки и изтриваше неизползваните обекти."

„Но този подход вече е изоставен. Колекторът за боклук от следващо поколение работи зад кулисите и на отделна нишка. Това се нарича едновременно събиране на боклук.“

"Разбирам. Как точно се взема решението за изтриване на обект or не?"

„Само преброяването на броя препратки към даден обект не е много ефективно – може да има обекти, които се препращат един към друг, но не са препращани от други обекти.“

„Така че Java използва различен подход.  Java разделя обектите на достижими и недостъпни.  Един обект е достижим (жив), ако е посочен от друг достижим (жив) обект. Достижимостта се определя от нишки. Работещите нишки винаги се считат за достижими (живи) , дори ако никой не ги споменава."

"ОК. Мисля, че разбирам."

„Как става действителното събиране на боклук – изтриването на ненужни обекти?“

„Просто е. В Java паметта е разделена на две части по конвенция и когато дойде време за събиране на боклука, всички живи (достъпни) обекти се копират в друга част от паметта и цялата стара памет се освобождава.“

„Това е интересен подход. Няма нужда да броите препратки: копирайте всички достъпни обекти и всичко останало е боклук.“

„Малко по-сложно е от това. Java програмистите установиха, че обектите обикновено се разделят на две категории: дълготрайни (които съществуват през цялото време, докато програмата работи) и краткотрайни (които са необходими в методите и за извършване на «локални " операции)."

"Много по-ефективно е дълголетните обекти да се държат отделно от краткотрайните. За да се направи това, беше необходимо да се измисли начин за определяне на дълголетието на обекта."

„И така, те разделиха цялата памет на „поколения“. Има обекти от първо поколение, обекти от второ поколение и т.н. Всеки път, когато паметта се изчиства, броячът на поколенията се увеличава с 1. Ако определени обекти съществуват в множество поколения, тогава те са записани като дълголетници."

„Днес събирачът на отпадъци е много сложна и ефективна част от Java. Много от неговите части работят евристично – въз основа на алгоритми, които правят предположения. В резултат на това той често „не слуша“ потребителя.“

"В смисъл?"

„Java има обект за събиране на отпадъци ( GC ), който може да бъде извикан с помощта на метода System.gc ().“

„Можете също така да използвате System.runFinalization() , за да принудите извикванията към методите за финализиране на обектите, които трябва да бъдат изтрити. Но факт е, че според documentацията на Java това гарантира, че нито събирането на отпадъци ще започне, нито че finalize( ) методът ще бъде извикан.  Събирачът на отпадъци решава кога да го извика и на Howво. "

"Уау! Добре е да знам."

„Но има още. Както знаете, в Java някои обекти препращат към други. Тази мрежа от препратки се използва, за да се определи дали даден обект трябва да бъде изтрит.“

"И вижте. Java има специални препратки, които ви позволяват да повлияете на този процес. Има специални обвиващи класове за тях. Ето ги:"

" SoftReference  е мека препратка."

" WeakReference  е слаба препратка."

" PhantomReference е фантомна справка."

„Ъъъ... Това ми напомня за вътрешни класове, вложени класове, вложени анонимни класове и локални класове. Имената са различни, но изобщо не е ясно за Howво служат.“

„Кажи, Амиго, ти си станал програмист. Сега си ядосан заради имената на класовете, казвайки, че «те не са достатъчно информативни и е невъзможно с едно име(!) да се определи Howво прави този клас, How, и защо"."

"Уау. Дори не забелязах. Но е толкова очевидно."

„Добре. Стига думи. Нека ви разкажа за SoftReferences.“

„Тези препратки са специално проектирани за кеширане, въпреки че могат да се използват и за други цели – всичко по преценка на програмиста.“

„Ето пример за такава препратка:“

Пример
// Create a Cat object
Cat cat = new Cat();

// Create a soft reference to a Cat object
SoftReference<Cat> catRef = new SoftReference<Cat>(cat);

// Now only the catRef soft reference points at the object
cat = null;

// Now the ordinary cat variable also references the object
cat = catRef.get();

// Clear the soft reference
catRef.clear();

„Ако единствените препратки към обект са меки, тогава той продължава да живее и се нарича „меко достъпен“.

"Но!  Обект, посочен само чрез меки препратки, може да бъде изтрит от събирача на отпадъци, ако програмата няма достатъчно памет.  Ако внезапно програмата няма достатъчно памет, преди да хвърли OutOfMemoryException , събирачът на боклук ще изтрие всички обекти препратен от меки препратки и ще се опита отново да разпредели памет за програмата."

„Да предположим, че клиентска програма често иска различни данни от сървърна програма. Сървърната програма може да използва SoftReference, за да кешира част от тях. Ако обекти, защитени от смърт чрез меки препратки, заемат голяма част от паметта, тогава събирачът на боклук просто ги изтрива всички. Красиво е!"

"Да. Аз самият го харесах."

„Е, едно малко допълнение: Класът SoftReference има два метода. Методът get() връща обекта, към който се отнася SoftReference . Ако обектът е бил изтрит от събирача на отпадъци, методът get () внезапно ще започне да връща нула.“

„Потребителят може също така изрично да изчисти SoftReference чрез извикване на метода clear(). В този случай слабата връзка вътре в обекта SoftReference ще бъде унищожена.“

"Това е всичко за сега."

„Благодаря за интересната история, Ели. Наистина беше много интересна.“