Я новачок у Java і розгублений щодо збору сміття на Яві. Що це насправді робить і коли вступає в дію. Опишіть, будь ласка, деякі властивості сміттєзбірника на Яві.
Я новачок у Java і розгублений щодо збору сміття на Яві. Що це насправді робить і коли вступає в дію. Опишіть, будь ласка, деякі властивості сміттєзбірника на Яві.
Відповіді:
Збір сміття - це програма, яка працює на віртуальній машині Java, яка позбавляється від об'єктів, які вже не використовуються додатком Java. Це форма автоматичного управління пам'яттю .
Коли типова програма Java працює, вона створює нові об'єкти, такі як String
s і File
s, але через певний час ці об’єкти більше не використовуються. Наприклад, погляньте на наступний код:
for (File f : files) {
String s = f.getName();
}
У наведеному вище коді String s
створюється значення для кожної ітерації for
циклу. Це означає, що на кожну ітерацію виділяється небагато пам’яті для створення String
об’єкта.
Повернувшись до коду, ми можемо побачити, що коли виконується одна ітерація, у наступній ітерації String
об’єкт, який був створений у попередній ітерації, вже не використовується - цей об’єкт тепер вважається "сміттям".
Врешті-решт, ми почнемо отримувати багато сміття, і пам’ять буде використовуватися для об’єктів, які вже не використовуються. Якщо це триває, з часом у віртуальної машини Java не вистачить місця для створення нових об'єктів.
Ось куди заходить смітник.
Збирач сміття шукатиме об’єкти, які вже не використовуються, і позбавляється від них, звільняючи пам'ять, щоб інші нові об’єкти могли використовувати цю частину пам'яті.
У Java управліннями пам’яттю опікується збирач сміття, але в інших мовах, таких як C, потрібно керувати пам’яттю самостійно, використовуючи такі функції, як malloc
іfree
. Управління пам’яттю - одна з тих речей, в яких легко помилитися, що може призвести до того, що називається витоком пам’яті - місця, де пам’ять не відновлюється, коли вони більше не використовуються.
Автоматичні схеми управління пам’яттю, як збирання сміття, дозволяють програмісту не так сильно переживати з питаннями управління пам’яттю, щоб він чи вона могли більше зосередитись на розробці необхідних для них програм.
Він звільняє пам'ять, виділену об'єктам, які програма вже не використовує - звідси і назва "сміття". Наприклад:
public static Object otherMethod(Object obj) {
return new Object();
}
public static void main(String[] args) {
Object myObj = new Object();
myObj = otherMethod(myObj);
// ... more code ...
}
Я знаю, що це надзвичайно надумано, але ось після того, як ви зателефонуєте, створене otherMethod()
оригінал Object
стає недоступним - і це "сміття", яке збирається сміттям.
У Java GC запускається автоматично, але ви також можете зателефонувати до нього System.gc()
і спробувати примусити головне збирання сміття. Як зазначає Паскаль Тівеннт, вам дійсно не слід цього робити, і це може принести більше шкоди, ніж користі (див. Це питання ).
Більше див. У статті Вікіпедії про збирання сміття та налаштування збору сміття (від Oracle)
System.gc()
не змушує GC працювати.
myObj
перед тим, як otherMethod
відбуватиметься виклик , оскільки в myObj
цей момент він більше не доступний.
System.gc()
, весь сенс мати GC - це не робити цього.
Об'єкт стає придатним для збору сміття або GC, якщо він недоступний з жодних прямих потоків або будь-яких статичних посилань.
Іншими словами, ви можете сказати, що об’єкт стає придатним для вивезення сміття, якщо всі його посилання є недійсними. Циклічні залежності не зараховуються як еталонні, тому якщо об’єкт A має посилання на об’єкт B, а об'єкт B має посилання на Об'єкт A, і вони не мають жодної іншої реальної посилання, то обидва об'єкти A і B будуть придатні до збору сміття.
Купи генерації для збору сміття -
Об'єкти Java створюються в Heap
і Heap
поділяються на три частини або покоління заради збирання сміття на Яві, вони називаються " Молодим (Новим) поколінням, Тенурованим (Старим) поколінням та Пермською областю купи.
Нове покоління далі поділяється на три частини, відомі як простір Ідена, простір Survivor 1 та Survivor 2. Коли об'єкт вперше створений у купі, його створюють у новому поколінні всередині простору Едема та після подальшого незначного збирання сміття, якщо об’єкт виживає, його переміщують у рятувальника 1, а потім уцілілого 2 до того, як основне збирання сміття перенесло цей об’єкт на старе або зайняте покоління .
Пермський простір Java Heap - це місце, де JVM зберігає метадані про класи та методи, дані про рядок рядків та рівні класу.
Детальніше див. Тут: Збір сміття
Ви не можете змусити JVM запустити збір сміття, хоча ви можете зробити запит за допомогою System.gc()
або Runtime.gc()
методу.
public static void gc() {
Runtime.getRuntime().gc();
}
public native void gc(); // note native method
Алгоритм маркування та перемикання -
Це один з найпопулярніших алгоритмів, що використовуються при збиранні сміття. Будь-який алгоритм збору сміття повинен виконувати 2 основні операції. По-перше, він повинен вміти виявляти всі недоступні об'єкти, а по-друге, він повинен повернути нагромаджений простір, який використовують сміттєві об'єкти, і знову зробити доступним простір для програми.
Вищеописані операції виконуються алгоритмом Марк і Змітання в дві фази:
читайте тут для більш детальної інформації - Алгоритм маркування та зачистки
Garbage Collector - це частина JRE, яка гарантує, що об'єкт, на який не посилаються, буде звільнений від пам'яті.
Зазвичай він запускається, коли у додатка не вистачає пам'яті. В AFAIK він містить графік, який представляє зв'язки між об'єктами та ізольованими об'єктами, які можуть бути звільнені.
Щоб зберегти продуктивність поточних об'єктів, згрупованих у покоління, кожен раз, коли GC сканує об'єкт і виявляє, що на нього все ще посилається кількість його генерації, збільшується на 1 (до деякого максимального максимального значення, 3 або 4, я думаю), і нове покоління сканується спочатку (чим коротший об'єкт в пам'яті, тим більше, ймовірно, він більше не потрібен), тому не всі об'єкти скануються кожного разу при запуску GC.
читайте це для отримання додаткової інформації.
Збір сміття дозволяє вашому комп'ютеру імітувати комп'ютер з нескінченною пам'яттю. Решта - це лише механізм.
Це робиться шляхом виявлення, коли шматки пам'яті більше не доступні з вашого коду, і повернення цих фрагментів у безкоштовний магазин.
EDIT: Так, посилання для C #, але C # і Java в цьому плані однакові.
Багато людей думають, що збирання сміття збирає та викидає мертві предмети.
Насправді збір сміття Java робить навпаки! Живі об’єкти відслідковуються, а все інше позначається сміттям.
Коли об'єкт більше не використовується, збирач сміття відновлює основну пам’ять і використовує його для подальшого виділення об'єкта. Це означає, що явного видалення немає і оперативна система не повертається. Щоб визначити, які об'єкти більше не використовуються, JVM з періодичністю виконує те, що дуже влучно називається алгоритмом розмітки.
Перевірте це для отримання більш детальної інформації: http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx
Якщо говорити про найпростіші терміни, які навіть непрограміст може зрозуміти, коли програма обробляє дані, вона створює проміжні дані та простір зберігання (змінні, масиви, певні метадані об'єкта тощо) для цих даних.
Коли доступ до цих об'єктів здійснюється через функції або певний розмір, вони виділяються з центральної купи. Потім, коли вони вже не потрібні, їх потрібно прибрати.
В Інтернеті є кілька дуже хороших статей про те, як це працює, тому я просто висвітлю саме основне визначення.
GC - це в основному функція, яка робить це очищення. Для цього очищаються записи таблиць, на які не посилаються жодні активні об'єкти, ефективно видаляючи об'єкти, ніж копіюються та ущільнюються пам'ять. Це трохи складніше, ніж це, але ви отримуєте ідею.
Велика проблема полягає в тому, що деякі частини цього процесу часто вимагають, щоб весь VM Java вимагав тимчасового припинення, щоб відбутися, а також весь цей процес дуже інтенсивний пропускну здатність процесора та пам'яті. Різні параметри як для GC, так і для налаштування варіантів для кожного з них призначені для збалансування цих різних проблем із усім процесом GC.
Збір сміття в Java (та інших мовах / платформах) - це спосіб для середовища виконання Java (JRE) повторно використовувати пам'ять з об'єктів Java, які вже не потрібні. Простіше кажучи, коли JRE спочатку запускається, він запитує Операційну систему (O / S) на певний об'єм пам'яті. Оскільки JRE запускає ваші програми (програми), він використовує цю пам'ять. Коли ваша програма виконана з використанням цієї пам’яті, приходить «Сміття сміття» JRE і повертає цю пам’ять для використання в різних частинах існуючих додатків. "Збір сміття" JRE - це фонове завдання, яке завжди працює і намагається вибрати час, коли система не працює, щоб продовжувати працювати зі сміттям.
Справжньою світовою аналогією були б смітники, які приходять до вас додому та забирають ваше сміття, яке можна переробити ... Зрештою, його повторно використати іншими способами та / або іншими людьми.
Сміттєзбірник можна розглядати як керівника підрахунку довідок. якщо об’єкт створений і його посилання зберігається у змінній, його кількість посилань збільшується на одиницю. під час виконання, якщо цій змінній присвоєно NULL. посилання на цей об'єкт зменшується. тож поточний номер відліку для об'єкта дорівнює 0. Тепер, коли виконується збір сміття, він перевіряє наявність об'єктів з опорним підрахунком 0. та звільняє виділені йому ресурси.
Викликання збирачів сміття контролюється політикою збору сміття.
Тут ви можете отримати деякі дані. http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html
Збір сміття є складовою jvm.
Він використовується для збору сміття, коли будь-який процесор стає безкоштовним.
Тут сміття означає невикористані об'єкти, які він працює у фоновому режимі основної програми
контролювати стан основної програми.
Автоматичне збирання сміття - це процес перегляду купи пам’яті, визначення того, які об’єкти використовуються, а які ні, та видалення невикористаних об’єктів. Об'єкт, що використовується, або об'єкт, на який посилається, означає, що частина частини вашої програми все ще підтримує вказівник на цей об'єкт. Невикористаний об'єкт або нереференційний об'єкт більше не посилається на жодну частину вашої програми. Таким чином, пам'ять, яку використовує необмежений об'єкт, може бути відновлена.
В такій мові програмування, як C, виділення та розміщення пам'яті є ручним процесом. У Java процес обміну пам'яттю обробляється автоматично сміттєзбірником. Перевірте посилання для кращого розуміння. http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
Збір сміття відноситься до процесу автоматичного звільнення пам'яті на купі, видаляючи об'єкти, які вже недоступні у вашій програмі. Купа - це пам'ять, яку називають безкоштовним магазином, являє собою великий пул невикористаної пам'яті, виділений для вашої програми Java.
Основні принципи збирання сміття - це пошук об’єктів даних у програмі, до яких не можна отримати доступ у майбутньому, та повернення ресурсів, які використовуються цими об'єктами. https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29
Переваги
1) Збереження від помилок, які виникають, коли звільнений фрагмент пам’яті, поки на нього ще є покажчики, і один із цих покажчиків перенавантажений. https://en.wikipedia.org/wiki/Dangling_pointer
2) Подвійні безкоштовні помилки, які виникають, коли програма намагається звільнити область пам'яті, яка вже звільнилася, і, можливо, вже була виділена знову.
3) Запобігає виникненню певних витоків пам'яті, коли програма не дозволяє звільнити пам'ять, зайняту об'єктами, які стали недосяжними, що може призвести до виснаження пам'яті.
Недоліки
1) Споживання додаткових ресурсів, вплив на продуктивність, можливі зупинки у виконанні програми та несумісність з ручним управлінням ресурсами. Збір сміття споживає обчислювальні ресурси, вирішуючи, яку пам'ять звільнити, хоча програміст, можливо, вже знав цю інформацію.
2) Момент, коли сміття насправді збирається, може бути непередбачуваним, внаслідок чого кінотеатри (паузи для зміни / вільної пам’яті) розсипаються протягом сеансу. Непередбачувані кіоски можуть бути неприйнятними в режимі реального часу, в обробці транзакцій або в інтерактивних програмах.
Підручник Oracle http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
Збір сміття - це процес виявлення, які об’єкти використовуються, а які ні, та видалення невикористаних об'єктів.
На мовах програмування, таких як C, C ++, виділення та звільнення пам'яті є ручним процесом.
int * array = new int[size];
processArray(array); //do some work.
delete array; //Free memory
Перший крок у процесі називається маркуванням. Тут збирач сміття визначає, які фрагменти пам'яті використовуються, а які - ні.
Крок 2а. Звичайне видалення видаляє нерозв'язані об'єкти, залишаючи посилаються об'єкти та покажчики на вільний простір.
Для підвищення продуктивності ми хочемо видалити невпорядковані об'єкти, а також ущільнити решта посилаються об'єктів. Ми хочемо зберегти посилання на об'єкти разом, тому буде швидше виділити нову пам'ять.
Як було сказано раніше, маркувати та ущільнювати всі об'єкти в JVM неефективно. Оскільки все більше і більше об'єктів виділяється, список об’єктів зростає і зростає, що призводить до більш тривалого і тривалого часу збору сміття.
Продовжуйте читати цей підручник, і ви дізнаєтесь, як GC приймає цей виклик.
Коротше кажучи, є три області купи, YoungGeneration для короткочасних об'єктів, OldGeneration для об’єктів тривалого періоду та PermanentGeneration для об'єктів, які живуть протягом життя додатків, наприклад, класи, бібліотеки.
Оскільки об'єкти динамічно розподіляються новим оператором, ви можете запитати, як ці об’єкти знищуються та як звільняється зайнята пам'ять. В інших мовах, таких як C ++, вам потрібно звільнити вручну виділені об'єкти динамічно оператором видалення. У Java є інший підхід; він автоматично обробляє розселення. Техніка відома як Збір сміття .
Це працює так: коли немає посилань на об'єкт, передбачається, що цей об’єкт більше не потрібен, і ви можете отримати пам'ять, зайняту об'єктом. Не потрібно явно знищувати об'єкти, як у C ++. Збір сміття відбувається епізодично під час виконання програми; Це не відбувається просто тому, що є один або кілька об'єктів, які вже не використовуються. Крім того, кілька реалізацій Java під час виконання сміття мають різні підходи до збору сміття, але більшості програмістів не потрібно переживати з цього при написанні програм.
Автоматичне збирання сміття - це процес, коли JVM позбавляється або зберігає в пам'яті певні точки даних, щоб остаточно звільнити місце для запущеної програми. Пам'ять спочатку надсилається в кучу пам'яті, тобто там, де збирач сміття (GC) виконує свою роботу, потім приймається рішення про припинення або збереження. Java передбачає, що програмісту не завжди можна довіряти, тому він припиняє елементи, які, на його думку, не потребує.