Подвержен ли Go тем же тонким утечкам памяти, что и Java?

89

Вот факты:

  • в языке Go есть сборщик мусора.

  • В Java есть сборка мусора

  • многие программы Java имеют (незаметные или нет) утечки памяти

В качестве примера Java-программы с утечками памяти (не для слабонервных, этот вопрос может поколебать ваши убеждения), посмотрите здесь о небольшой Java-программе под названием Tomcat, в которой даже есть кнопка «найти утечки»: Есть ли способ чтобы избежать утечек памяти в Tomcat?

Поэтому мне интересно: будут ли программы, написанные на Go, демонстрировать такие же (незаметные или нет) утечки памяти, которые обнаруживаются в некоторых программах, написанных на Java?

Синтаксис T3rr0r
источник
29
«У многих программ Java есть (незаметные или нет) утечки памяти», есть ли у вас какие-либо доказательства этого «факта» или это просто тема для разговора.
Питер Лоури,
17
@Webinator: Думаю, вам нужно привести пример одной из этих «тонких утечек памяти», которые есть у «многих» программ Java. Если вы не заявляете об ошибке в сборщике мусора, единственный способ утечки памяти в чистой Java - это удерживать ссылки, которые вы больше не используете, например, помещая объекты в коллекцию и никогда не удаляя их из этой коллекции. Если вы имеете в виду именно такую ​​утечку, то ни один язык в мире не защитит от них, включая Go.
JeremyP
14
Вот утечки памяти, о которых я говорил (+200 голосов за, ответы с +150 голосов за, объяснение множества фактических утечек памяти Java): stackoverflow.com/questions/6470651/…
SyntaxT3rr0r
6
Конечно, у программ JAVA есть утечки памяти, просто забудьте установить некоторую ссылку на ноль, когда они больше не нужны. Часто встречается в больших постоянных коллекциях (например, кэшах) с шаблоном проектирования наблюдателя или локальными переменными потока. Это не теоретически, несколько утечек памяти я исправил сам в продакшене. И это не анти Ява. Я занимаюсь JAVA-разработкой на полную ставку более 5 лет, работаю над множеством разных проектов. Непонимание того, что у вас может быть утечка памяти в JAVA (или на любом другом существующем языке), - это не фанатизм, а скорее непонимание того, как все работает на самом деле.
Николя Буске
6
В этом вопросе можно обойтись без драматизма и комментариев о «фанатизме», «расшатывании чужих убеждений» и тому подобном. Esp. поскольку вся дискуссия сводится к тому, что «мое определение memory leakлучше вашего».
LAFK требует восстановить Монику

Ответы:

44

Здесь вы путаете разные типы утечек памяти.

Ужасные утечки памяти, основанные на явном управлении памятью, исчезли в Java (или любом другом языке, основанном на сборке мусора). Эти утечки вызваны полной потерей доступа к фрагментам памяти без пометки их как неиспользуемых.

«Утечки памяти» все еще присутствуют в Java и во всех других языках на планете, пока компьютер не сможет читать наши мысли, все еще с нами и будут в обозримом будущем. Эти утечки вызваны тем, что код / ​​программист хранит ссылки на объекты, которые технически больше не нужны. Это принципиально логические ошибки, и их нельзя предотвратить ни на одном языке с помощью современных технологий.

Джеймс
источник
23
Утечка памяти - это просто когда вы забываете освободить память. В Java это происходит, когда вы забываете установить ссылки на null. В C ++ такое бывает, если вы забыли позвонить бесплатно. Оба являются допустимыми случаями утечки памяти. И основная проблема та же самая: ваша программа потребляет все больше и больше памяти, пока в конечном итоге не выйдет из строя с ошибкой OutOfMemory.
Николя Буске
1
Хотя верно то, что ни один язык не может помешать программисту совершать такие логические ошибки, также верно и то, что некоторые такие ошибки существуют в самом Java SDK (см., Например, java.util.logging.Levelкоторый содержит частную статику, ArrayListв которую все такие созданные объекты помещены в конструкцию и из которых они никогда не удаляются), что затрудняет их предотвращение при программировании Java, чем на каком-либо другом языке, который не содержит таких недостатков
Жюль
7
Я думаю, что OP спрашивал об утечках памяти объектов, которые действительно недоступны, как в принятом ответе на связанный вопрос. Утечка памяти, вызванная загрузкой класса из потоков. -1
qbt937 02
1
Также возможно, что статический анализ может определить, продолжают ли ссылки существовать после их полезного срока службы - чтение мыслей не требуется.
Кайл Стрэнд
1
@Amrit Нет, сборщик мусора собирает память, на которую у вас больше нет ссылок. У него нет возможности узнать, можно ли удалить то, на что у вас еще есть ссылка.
Рафаэль Шмитц
19

Вполне возможно, что программы Go будут демонстрировать утечки памяти. Текущая реализация Go имеет простой сборщик мусора с функцией отметки и очистки. Это задумано только как временное решение и не предназначено как долгосрочный сборщик мусора. См. Эту страницу для получения дополнительной информации. Загляните под шапку Go Garbage Collector. На этой странице даже есть ссылка на код для текущей версии, если вы так хотите.

Poindexter
источник
1
Одна из проблем сборщика меток и зачисток в Java - это фрагментация памяти. Хотя технически это не является памятью, это может быть потеря памяти, доступной для приложения.
Питер Лоури,
9

«Утечка памяти» - это когда часть памяти, которая, по мнению программиста, должна быть освобождена, не освобождается. Это может происходить на любом языке, вне зависимости от того, выполняется сборка мусора или нет. Обычная причина в языках GC - сохранение дополнительной ссылки на память.

«Языки не вызывают утечек памяти, программисты вызывают утечки памяти».

DJClayworth
источник
8

Сборка мусора или нет, но вы можете написать программу с утечками памяти на Java, Go или любом другом языке по большей части.

Сборка мусора частично снимает нагрузку с программиста, но не предотвращает полностью утечки.

jzd
источник
4
Я знаю я знаю. Я говорю конкретно о тонких утечках памяти, которые существуют в Java, даже несмотря на то, что жесткая Java вначале продавалась как язык, где утечек памяти не существует благодаря GC .
SyntaxT3rr0r
4
Извините, что было непонятно. Вы сказали: «У многих программ Java есть (незаметные или нет) утечки памяти».
jzd
3

Здесь вы смешиваете уровни абстракции: утечки памяти происходят из-за ошибок в библиотеке (где объекты ссылаются друг на друга, хотя цепочки `` удерживает ссылку на b '', а также компромисс при реализации сборщика мусора между эффективностью и точность. Сколько времени вы хотите потратить на обнаружение таких петель? Если вы потратите в два раза больше, вы сможете обнаруживать петли в два раза дольше.

Таким образом, проблема утечки памяти не связана с конкретным языком программирования, и нет причин, по которым GO должен быть лучше или хуже, чем Java.

флорин
источник
1
Я не совсем согласен. Утечки памяти связаны с тем, что Java позволяет выстрелить себе в ногу, и это не обязательно связано с ошибкой библиотек. Многие программисты пишут программы, которые медленно, но верно вызывают утечку памяти на Java, и это их собственная ошибка, а не ошибка библиотек. Кроме того, если именно Java GC идет на компромисс между временем и возможной утечкой, идет ли Go на такие же компромиссы?
SyntaxT3rr0r
1
и вопрос действительно не в том, «сколько времени я хочу потратить на обнаружение таких петель?» Вопрос в том, «Сколько времени, согласно спецификации, Go GC тратит на такие циклы» , ИМХО это интересный вопрос.
SyntaxT3rr0r
16
Циклические цепочки ссылок не предотвращают сборку мусора в Java.
Энди Томас,