Go підлягає тим самим тонким витокам пам'яті, що і Java?


89

Ось факти:

  • мова Go має збирач сміття.

  • Java має збір сміття

  • багато програм Java мають (незначні чи ні) витоки пам'яті

Як приклад програми Java, яка має витоки пам’яті (не для слабонервних, питання може похитнути ваші переконання), див. Тут про невелику програму Java під назвою Tomcat, яка навіть має кнопку "знайти витоки": чи є спосіб щоб уникнути нерозгортання витоків пам'яті в Tomcat?

Тому мені цікаво: чи будуть програми, написані на Go, виявляти такий самий (витончений чи ні) витік пам'яті, який демонструють деякі програми, написані на Java?


29
"у багатьох програмах Java спостерігається (незначний чи ні) витік пам'яті", чи є у вас якісь докази цього "факту", чи це просто розмова.
Пітер Лорі

17
@Webinator: Я думаю, вам потрібно навести приклад одного з цих "тонких витоків пам'яті", які "багато" програм Java. Якщо ви не заявляєте про помилку в колекторі сміття, єдиний спосіб витоку пам’яті в чистій Java - це триматися посилань, які ви вже не використовуєте, наприклад, поміщаючи об’єкти в колекцію і ніколи не вилучаючи їх із цієї колекції. Якщо ви маєте на увазі саме такий витік, то жодна мова у світі не захистить від них, включаючи Go.
JeremyP

14
Ось витоку пам'яті я говорю про (+200 upvotes, відповіді з +150 upvotes, багато фактичних витоків пам'яті Java пояснено): stackoverflow.com/questions/6470651 / ...
SyntaxT3rr0r

6
Звичайно, програми JAVA мають витік пам'яті, просто забудьте встановити посилання на null, коли вони вам більше не потрібні. Часто трапляється у великих постійних колекціях (наприклад, кешах) із шаблоном дизайну спостерігача або локальними змінними потоку. Це не теоретично, я виправив кілька витоків пам'яті сам у виробництві. І це не анти Java. Я штатний розробник JAVA більше 5 років, працюю над багатьма різними проектами. Не визнаючи, що у вас може бути витік пам’яті в JAVA (або в усіх інших існуючих мовах), це не фанбоїзм, а більше відсутність розуміння того, як насправді все працює.
Ніколя Буске

6
Це питання могло б обійтися без драми та коментарів про "фанбоїзм", "похитування переконань когось" тощо. Особливо оскільки вся дискусія зводиться до "моє визначення memory leakкращого за ваше".
LAFK каже "Відновити Моніку"

Відповіді:


44

Ви плутаєте тут різні типи витоків пам'яті.

Неприємні витоки пам'яті на основі управління явною пам'яттю зникли в Java (або будь-якій іншій мові на основі GC). Ці витоки спричинені повністю втратою доступу до фрагментів пам'яті, не позначаючи їх як невикористані.

"Витік пам'яті", як і раніше присутній у Java та будь-якій іншій мові на планеті, поки комп'ютер не зможе читати наші думки, все ще з нами, і буде в найближчому майбутньому. Ці витоки спричинені тим, що код / ​​програміст зберігає посилання на об'єкти, які технічно більше не потрібні. Це принципово логічні помилки, і їх не можна запобігти жодною мовою за допомогою сучасних технологій.


23
Витік пам’яті - це просто тоді, коли ви забули звільнити пам’ять. У Java це відбувається, коли ви забули встановити посилання на null. У C ++ це трапляється, якщо ви забули зателефонувати безкоштовно. Обидва вони є дійсними випадками витоку пам'яті. І фундаментальна проблема та сама, ви програмуєте все більше і більше пам'яті, поки вона врешті не вийде з ладу OutOfMemory.
Ніколя Буске

1
Хоча правда, що жодна мова не може перешкодити програмісту робити такі логічні помилки, правда також є те, що деякі такі помилки існують у самому Java SDK (див., Наприклад, java.util.logging.Levelякий містить приватну статику, ArrayListв яку всі такі побудовані об'єкти розміщені на конструкції і з яких вони ніколи не видаляються), що ускладнює їх уникнення при програмуванні Java, ніж в іншій мові, яка не містить таких недоліків
Жюль

7
Я думаю, що OP запитував про витоки пам’яті об’єктів, які насправді недосяжні, як у прийнятій відповіді на пов'язане питання. Витік пам'яті, спричинений завантаженням класу з потоків. -1
qbt937

1
Можливо також, що статичний аналіз міг би визначити, чи існують посилання і надалі протягом свого корисного життя - читання розуму не потрібно.
Kyle Strand

1
@Amrit Ні, збирач сміття збирає пам’ять, на яку у вас більше немає посилань. Він ніяк не може знати, чи добре видаляти те, на що у вас все ще є посилання.
Рафаель Шміц,

19

Цілком можливо, що програми Go виявлятимуть витоки пам'яті. Поточна реалізація Go має простий збирач сміття. Це призначено лише як тимчасове рішення, а не як довготривалий збирач сміття. Докладніше див. На цій сторінці . Подивіться під заголовок Go Garbage Collector. Ця сторінка навіть має посилання на код для поточної версії, якщо ви так схильні.


1
Однією з проблем колектора меток і розгортки в Java є фрагментація пам'яті. Хоча технічно це не пам’ять, це може втратити пам’ять, доступну для програми.
Пітер Лорі

9

`` Витік пам'яті '' - це коли частина пам'яті, яку програміст вважав би звільненою, не звільниться. Це може статися будь-якою мовою, зібраним сміттям чи ні. Звичайною причиною для мов GC є збереження додаткового посилання на пам'ять.

Msgstr "Мови не викликають витоків пам'яті, програмісти викликають витоки пам'яті".


8

Збір сміття чи ні, ви можете написати програму, яка здебільшого втрачає пам’ять у Java, Go або будь-якій іншій мові.

Збір сміття знімає певний тягар з програміста, але це не запобігає витокам повністю.


4
Я знаю, я знаю. Я говорю конкретно про дещо тонкі витоки пам’яті, які існують у Java, навіть непроста Java на початку її продавали як мову, де витоків пам’яті не існує завдяки GC .
SyntaxT3rr0r

4
Вибачте, що не було зрозуміло. Ви сказали: "у багатьох програмах Java спостерігається (незначний чи ні) витік пам'яті".
jzd

3

Ви змішуєте тут рівні абстракції: витоки пам’яті пов’язані з помилками в бібліотеці (де об’єкти посилаються один на одного, хоча ланцюжки „a містить посилання на b“), а також компромісом у реалізації збирача сміття між ефективністю та точність. Скільки часу ви хочете витратити на пошук таких петель? Якщо ви витратите вдвічі більше, ви зможете виявити петлі вдвічі довше.

Отже, проблема витоку пам’яті не стосується мови програмування, немає жодної причини, що сама по собі GO повинна бути кращою чи гіршою за Java.


1
Я не повністю згідний. Витоки пам’яті пов’язані з тим, що Java дозволяє пострілювати собі в ногу, і це не обов’язково пов’язано з помилкою бібліотек. Багато програмістів пишуть програми, які повільно, але впевнено втрачають пам'ять на Java, і це їх власна вина, а не вина бібліотек. Крім того, якщо саме Java GC робить компроміс із часом / можливим витоком, Go робить ті самі компроміси?
SyntaxT3rr0r

1
і питання насправді не в "скільки часу я хочу витратити на пошук таких петель?" Питання полягає в тому, "скільки часу специфікації вимагають, щоб Go GC витрачав на такі петлі" , що IMHO є цікавим питанням.
SyntaxT3rr0r

16
Циклічні посилальні ланцюги не перешкоджають збору сміття на Java.
Енді Томас,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.