LINUX.ORG.RU

Целенаправленные утечки памяти в некоторых специальных случаях.

 ,


1

2

Имеет ли смысл на онтопике и других юниксах не освобождать выделенную в куче неиспользуемую память вручную, если известно, что программа скоро будет завершена и вся память программы станет освободится автоматически?

Например, где-то там, в одной из функций инициализируется

static char** string_array; //глобальная переменная

Допустим, вместо того, чтобы освобождать эту память, я так и оставляю её «висеть», т.к. известно, что программа представляет собой консольную утилиту без интерактивного взаимодействия и за разумное время она всё равно завершит свою работу и память будет возвращена системе.

★★★★★
Ответ на: комментарий от emulek

Вообще-то, возможно. Во-первых, ОС и файлодескриторы закроет автоматически, во-вторых: on_exit() / atexit(). Хотя, вот дескрипторы файлов лучше, конечно, закрывать вручную.

anonymous
()
Ответ на: комментарий от korvin_

Почему сразу дву-?

потому что 2*8. Ну или отдельный список с указателями на ноды. В любом случае это избыточно.

emulek
()
Ответ на: комментарий от anonymous

Вообще-то, возможно.

да я и без тебя знаю, что говнокод возможен.

ОС и файлодескриторы закроет автоматически

в хелловорлде — да. В сложном проекте — hz.

emulek
()
Ответ на: комментарий от emulek

ты всё равно не поймёшь

я все еще жду объяснений, трепло ты наше

и я не царь, правила футбола знаю, в отлии от

anonymous
()
Ответ на: комментарий от emulek

в хелловорлде — да. В сложном проекте — hz.

Вещества какие-то. Закроет ОС вам дескрипторы, инфа соточка. Если, конечно, это не гипотетическая ОС killcoderix-lor-edition.

anonymous
()
Ответ на: комментарий от anonymous

Закроет ОС вам дескрипторы

вопрос КОГДА закроет? А если я повторно его открою?

Такие как ты дебилы пейсали ПО вроде гуглохрома, которое течёт, причём течёт в Xorg. В итоге, если гуглохром закрыть/открыть, то памяти от этого не прибавится, необходимо рестартовать Xorg, что не слишком-то и удобно. Тоже наверное думали «система всё сама подчистит»…

emulek
()
Ответ на: комментарий от emulek

Говнокод - это когда ты оставляешь возможность сделать стейт своего приложения некорректным (оставляешь возможность освобождения памяти).

anonymous
()
Ответ на: комментарий от emulek

А можно пример таких сложных случаев?

anonymous
()
Ответ на: комментарий от emulek

вопрос КОГДА закроет?

Когда процесс завершится.

А если я повторно его открою?

Все, нет у тебя больше процесса.

Такие как ты дебилы пейсали ПО вроде гуглохрома, которое течёт, причём течёт в Xorg. В итоге, если гуглохром закрыть/открыть, то памяти от этого не прибавится, необходимо рестартовать Xorg, что не слишком-то и удобно. Тоже наверное думали «система всё сама подчистит»…

Не надо делать API, который такую херню будет позволять. Тогда такие дебилы, как я, не накосячат. И тут еще посмотреть надо, а нет ли багов в хорге.

anonymous
()
Ответ на: комментарий от anonymous

Так то что хорг течет - проблема хорга, а не хрома, лол.

тогда объясни мне, лолка, почему Xorg течёт только при запущенном гуглохроме?

emulek
()
Ответ на: комментарий от emulek

тогда объясни мне, лолка, почему Xorg течёт только при запущенном гуглохроме?

Очевидно, что конкретно гуглохром использует возможности хорга так, что это приводит к багу в хорге. Вполне возможно, что такое и в других приложениях встречается - просто они меньше гуглохрома распространены и никто не замечает.

anonymous
()
Ответ на: комментарий от anonymous

Все, нет у тебя больше процесса.

ага. А если я открою ДО завершения?

Не надо делать API, который такую херню будет позволять. Тогда такие дебилы, как я, не накосячат. И тут еще посмотреть надо, а нет ли багов в хорге.

тут проблема не в API, а в том, что этот API Xorg'а неправильно использовали. Понадеялись на то, что память «сама освободиться», но не тут-то было.

А можно пример таких сложных случаев?

в примере ТСа можно сделать у каждой ноды деструктор, который в отладочной версии считает число узлов, это позволит проверять корректность структур, например находить «мёртвые» ноды, которые не связаны с графом. Но для этого нужно _явное_ удаление ненужных нод. Дабы не получилось так, что нода не нужна, но она ещё существует. Можно ещё и добиться ускорения кода, и сэкономить память, если ненужные ноды при удалении не удалять, а сцеплять в список свободных нод. Этот список позволит быстро получать новые ноды. Также сэкономить время и память можно выделяя ноды пуллами по Over9000 штук. У ТСа ноды маленькие, и это поможет. Но для всего этого нужен явный delete.

Можно и более мощный механизм замутить, с GC например и без явного удаления(т.е. ноды не нужно будет удалять, они сами будут удаляться, когда нужно. Например когда они отцеплены от главного графа).

emulek
()
Ответ на: комментарий от anonymous

Очевидно, что конкретно гуглохром использует возможности хорга так, что это приводит к багу в хорге.

дык почему создатели гуглохрома это не исправят? Это ведь не только баг, но и потенциальная дыра. А не исправляют очевидно потому, что write-only говнокод.

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

может и встречается. Это как-то оправдывает хром?

emulek
()

Ты только что потратил час на то чтобы поразмышлять «а следует ли так делать», после чего пришел на ЛОР и потратил еще час обсасывая это здесь.

Может проще написать free? Это бы заняло у тебя на 1:59 меньше.

morse ★★★★★
()
Ответ на: комментарий от cord

Наоборот, код будет проще.

если структура очень сложная, как пишет ТС, то код будет конечно проще, но памяти жрать будет намного больше, ибо ВСЕ узлы будут висеть в памяти до победного конца. В том числе и не нужные.

Как ты думаешь, зачем во всех ЯП с GC есть оператор/функция unset?

emulek
()
Ответ на: комментарий от morse

не, он хочет как в пхп, что-бы «само». ИЧСХ, в C++ это возможно.

emulek
()
Ответ на: комментарий от emulek

ага. А если я открою ДО завершения?

См пункт первый. Процесс завершается, ОС освобождает ресурсы.

тут проблема не в API, а в том, что этот API Xorg'а неправильно использовали. Понадеялись на то, что память «сама освободиться», но не тут-то было.

Нет, тут проблема в API. Если API позволяет вычерпать ресурсы, плюнув на лимиты, именно так этим API и воспользуются. Если API позволяет сделать утечки, то утечки будут. Не потому, что быдлокодеры тупые, а потому что все люди ошибки делают. Завершится твой клиент по сигналу, не отдаст ресурсы и все, память ПОТРАЧЕНА.

anonymous
()
Ответ на: комментарий от morse

у кого-то уходят годы на выработку правильных методов написания кода на сях, а тут всего-то пара часов

unt1tled ★★★★
()
Ответ на: комментарий от anonymous

См пункт первый. Процесс завершается, ОС освобождает ресурсы.

вот только в коде будет утерян файл, я буду в другой файл писать, а не в первый.

Если API позволяет сделать утечки, то утечки будут.

API который позволяет утечки намного дешевле. И быстрее и памяти меньше ест. API который «не позволяет утечки» это API с встроенным GC, который не знает и не может знать, когда память стала «мусором».

а потому что все люди ошибки делают.

вот именно по этому должен быть _явный_ код делающий free(3). В отладочной версии туда можно вставить проверку, хотя-бы просто проверяющую, что free(3) выполнилось ровно столько раз, сколько было malloc(3). А лучше сделать свою коллекцию областей памяти, например простым односвязанным списком. Тогда можно будет всегда проконтролировать, были утечки или нет. В обычной сишке это сложно, но в C++ я не вижу проблемы, ведь new и delete можно перегружать по своему. А файловый IO не только можно, но и нужно, т.к. файловых операций в самой сишке нет(STL stream это тоже обёртка).

Завершится твой клиент по сигналу, не отдаст ресурсы и все, память ПОТРАЧЕНА.

в таком случае сигнал надо перехватить.

emulek
()
Ответ на: комментарий от emulek

потому что 2*8

-- это только для связей нод, а сами данные?

korvin_ ★★★★★
()
Ответ на: комментарий от emulek

почему Xorg течёт только при запущенном гуглохроме?

потому что де-факто/де-юро это сетевой протокол. Сервер выделяет/освобождает ресурсы только по команде клиента. Если клиент не командует освободить ресурсы - они будут заняты (читай заюзана/течёт память) до конца сессии. Причём сессия != TCP_соединение. Постоянная «утечка» на стороне сервера может быть вызвана JS движком на стороне клиента с любимым многими тут garbage-collector. Есть случаи (и легион их) когда пока копеечный объект в клименте не будет окончательно прибит и освобождён, толстенный ресурс сервера будет занят.

но во первых ты это и так знаешь и зря флуд поднимаешь, во вторых к теме поднятой ТС не имеет никакого отношения.

MKuznetsov ★★★★★
()
Последнее исправление: MKuznetsov (всего исправлений: 1)
Ответ на: комментарий от emulek

вот только в коде будет утерян файл, я буду в другой файл писать, а не в первый.

Код теряет управление при завершении процесса.

В обычной сишке это сложно

Линковать со своими malloc/free или использовать готовые инструменты типа valgrind/gperftools?

файловых операций в самой сишке нет

fukkk...

motto
()
Ответ на: комментарий от emulek

вот только в коде будет утерян файл, я буду в другой файл писать, а не в первый.

Я не понял, при чем тут close(), который (условно) сделает ОС после завершения процесса.

API который позволяет утечки намного дешевле. И быстрее и памяти меньше ест.

Это DOS.

API который «не позволяет утечки» это API с встроенным GC, который не знает и не может знать, когда память стала «мусором».

Столько страшных слов для простой мысли: процесс владеет ресурсами. Завершился процесс - освобождай ресурсы. В X'ах есть концепция соединения, разорвалось соединение - освобождай ресурсы, поэтому я уверен, что это был баг в Xах.

вот именно по этому должен быть _явный_ код делающий free(3). В отладочной версии туда можно вставить проверку, хотя-бы просто проверяющую, что free(3) выполнилось ровно столько раз, сколько было malloc(3). А лучше сделать свою коллекцию областей памяти, например простым односвязанным списком. Тогда можно будет всегда проконтролировать, были утечки или нет. В обычной сишке это сложно, но в C++ я не вижу проблемы, ведь new и delete можно перегружать по своему. А файловый IO не только можно, но и нужно, т.к. файловых операций в самой сишке нет(STL stream это тоже обёртка).

Я не понял, как это связано с ОС и ее надежностью.

в таком случае сигнал надо перехватить.

Перехватил SIGSEGV, память - в кашу, дескрипторы испортились. Что дальше?

Нахрен вообще делать DOSы, если можно не делать? Давайте еще по разу по всем историческим граблям пройдемся: с одного раза непонятно же, что другим процессам нельзя доверять, особенно нельзя доверять СЕРВИСУ, который не один процесс обслуживает.

anonymous
()
Ответ на: комментарий от anonymous

Охренеть, Х'ы действительно можно попросить не освобождать ресурсы завершившегося процесса. Ммм, этот вкус и запах 95й винды...

anonymous
()
Ответ на: комментарий от anonymous

Нахрен вообще делать DOSы, если можно не делать?

потому что с твоим подходом получится Windows.

я уверен, что это был баг в Xах.

а почему данный баг не проявляется с FireFox? Какой-то другой Xorg, да?

emulek
()
Ответ на: комментарий от emulek

потому что с твоим подходом получится Windows.

Передергиваешь.

а почему данный баг не проявляется с FireFox? Какой-то другой Xorg, да?

Потому, что это баг. Какой-то другой паттерн использования API, какие-то другие функции, да.

anonymous
()
Ответ на: комментарий от next_time

допустим, она в процессе работы создаёт куда больше объектов, которые друг на друга указывают, создавая посредством указателей сложный граф. все эти объекты создаются внутри каких-то методов динамически и их удаление становится нетривиальной задачей

А вот это уже проблема проектирования

CyberK
()
Ответ на: комментарий от anonymous

Х'ы действительно можно попросить

«попросить» и «не освободить самому» это таки немного разное

anonymous
()
Ответ на: комментарий от emulek

дык почему создатели гуглохрома это не исправят?

почему создатели хрома должны исправлять глюки хорга?

может и встречается. Это как-то оправдывает хром?

При чем тут вообще хром, если глючит хорг? Пусть разработчики хорга и исправляют свое глючное апи.

anonymous
()
Ответ на: комментарий от emulek

то код будет конечно проще, но памяти жрать будет намного больше, ибо ВСЕ узлы будут висеть в памяти до победного конца. В том числе и не нужные.

Так у него все узлы нужные, в том и штука.

anonymous
()
Ответ на: комментарий от anonymous

Х'ы действительно можно попросить не освобождать ресурсы завершившегося процесса.

Ай лолд. Какой в этом смысл вообще?

anonymous
()
Ответ на: комментарий от emulek

а почему данный баг не проявляется с FireFox? Какой-то другой Xorg, да?

Очевидно потому, что файрфокс не использует определенные возможности апи хорга так, как их использует хром. По-этому баг не проявляется. Баг проявляется только во вполне определенных обстоятельствах. Что тут непонятного?

anonymous
()
Ответ на: комментарий от anonymous

почему создатели хрома должны исправлять глюки хорга?

почему нет? Если это действительно баг xorg'а, то прочему не отписаться в bug tracker?

При чем тут вообще хром, если глючит хорг? Пусть разработчики хорга и исправляют свое глючное апи.

а отписаться в багзиллу религия не велит?

emulek
()
Ответ на: комментарий от anonymous

Так у него все узлы нужные, в том и штука.

если все узлы нужные, то удалять их конечно необязательно.

Проблема в том, что это _сейчас_ так, а завтра он захочет удалять, и вот тут-то и начнутся проблемы, т.к. удаление он в принципе не желает реализовывать.

emulek
()

Имеет ли смысл на онтопике и других юниксах не освобождать выделенную в куче неиспользуемую память вручную

Если нет каких-либо особых условий, то я делал бы следующим образом: память всё-таки освобождал, но если это стало бы проблемой (или если очень хочется), то завершался бы по std::quick_exit.

DarkEld3r ★★★★★
()
Ответ на: комментарий от emulek

почему ТС не может в ноде сделать поле «next», превратив таким образом эти ноды в список?

так лучше, да, но я отвечал на это: Целенаправленные утечки памяти в некоторых специальных случаях. (комментарий)

а там mtk предлагал именно прямой подход (очевидно, через std::forward_list).

next_time ★★★★★
() автор топика
Ответ на: комментарий от DarkEld3r

в теории, освобождение памяти системой должно выполняться несколько быстрее, чем программой

next_time ★★★★★
() автор топика
Ответ на: комментарий от next_time

в теории, освобождение памяти системой должно выполняться несколько быстрее, чем программой

Я исходил из того, что обычно освобождение не требует особенных усилий, поэтому написать его не сложно. Да и код более идеоматическим получается - принцип наименьшего удивления и всё такое.

Опять же, вдруг потом захочется несколько раз за время работы освобождать/выделять память. В таком случае, проще будет рефакторить/переделывать.

DarkEld3r ★★★★★
()
Ответ на: комментарий от emulek

а отписаться в багзиллу религия не велит?

Очевидно, для этого надо сперва понять в чем состоит баг.

anonymous
()
Ответ на: комментарий от emulek

Проблема в том, что это _сейчас_ так, а завтра он захочет удалять

Еще раз, согласно спецификации любое удаление любого узла приводит программу к некорректному состоянию и программа должна быть закрыта, дальше работать она не имеет права. Таковы условия описанные в оп-посте. То что в других каких-то условиях память освобождать надо - ни у кого сомннений не вызывает. Речь идет конкретно об этих.

anonymous
()
Ответ на: комментарий от DarkEld3r

Опять же, вдруг потом захочется несколько раз за время работы освобождать/выделять память.

никак ничему не помешает

принцип наименьшего удивления и всё такое.

тогда можно забыть про С++ и писать на С

next_time ★★★★★
() автор топика
Ответ на: комментарий от emulek

API который «не позволяет утечки» это API с встроенным GC, который не знает и не может знать, когда память стала «мусором».

кстати, я правильно понимаю, что вы сейчас «ругаете» меня за подход, который оправдываете у разработчиков Xorg?

только (разница не в пользу х-ов) в предложенном мною случае, программу легко прибить, и более того, она сама гарантированно это сделает, а вот х-ы...

next_time ★★★★★
() автор топика
Ответ на: комментарий от next_time

никак ничему не помешает

В смысле? Если освобождение памяти уже предусмотрено, то его не придётся писать, если вдруг понадобится. Всякие экзотические случаи не рассматриваем.

тогда можно забыть про С++ и писать на С

Логики не понял. Можно подробнее? Или это намёк на то, что «С проще»? Так ведь дело не в сложности языка, а в том, что есть общепринятые практики. Например, можно городить аналог finally из других языков (и да, оно иногда удобнее), но идеоматически будет всё-таки использовать RAII.

Ну и наличие множества фич вполне может облегчать написание и чтение кода.

Ну и отвечал я в контексте первого сообщения. Всякие там «произвольные графы» появились потом. Так-то я против догматизма, поэтому если надо, то не вижу ничего плохого в не освобождении.

DarkEld3r ★★★★★
()
Ответ на: комментарий от anonymous

Очевидно, для этого надо сперва понять в чем состоит баг.

за хромиумом я такого не замечал, а код гуглохрома закрыт. Т.ч. это пусть сами разрабы разбираются, почему Xorg глючит именно с их поделием.

emulek
()
Ответ на: комментарий от anonymous

Речь идет конкретно об этих.

я уже написал: в конкретно этих не имеет значения. AFAIK оверхед на удалении минимальный, т.ч. я не думаю, что это можно будет хотя-бы заметить.

В данном случае можно сделать delete, который ничего не делает. Оптимизирующий компилятор его выкинет, и код будет работать так, как хочет ТС. С другой стороны, в исходнике будет вызываться delete.

emulek
()
Ответ на: комментарий от next_time

принцип наименьшего удивления и всё такое.

тогда можно забыть про С++ и писать на С

нет. Если вы в C++ сказали new, вы _обязаны_ сказать delete. Иначе вы пхп-обезьяна.

кстати, я правильно понимаю, что вы сейчас «ругаете» меня за подход, который оправдываете у разработчиков Xorg?

угу. Но Xorg это очень древний проект, и Ъ-решение в те далёкие годы не взлетело-бы. Тот же ansi C не позволяет строить удобные интерфейсы с наследованием и инкапсуляцией. Получаются убогие нечитаемые монстры с жутким оверхедом. Да ещё с очень «хорошим» типом данных void*. А клиенты API потому удивляются: почему их код собирается, но жутко глючит?

только (разница не в пользу х-ов) в предложенном мною случае, программу легко прибить, и более того, она сама гарантированно это сделает, а вот х-ы...

дело в подходе. Систему тоже можно попросить выделить память в файле. Она этот файл потом закроет, но не удалит, так он и останется на диске(даже если он временный, и по логике дальше памяти пойти не должен. Но система-то не в курсе, вот она его и закрывает, т.е. сохраняет из файлового кеша на диск. И долго, и место на диске теряется).

emulek
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.