LINUX.ORG.RU

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

 ,


1

2

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

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

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

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

★★★★★

Не даст ли такое поведение дополнительный чрезмерный оверхед, или, может, наоборот, в некоторых сложных случаях позволит на 5 копеек увеличить быстродействие?

next_time ★★★★★
() автор топика

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

Если это модуль синглтон с функциями init, destroy и instance, то валяй. Вот только что тебя останавливает от того что бы таки освободить память?

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

предполагается, что вся её жизнь — в некотором роде, завершение)

next_time ★★★★★
() автор топика

за разумное время она всё равно завершит свою работу

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

но есть пара других нюансов:

1) программа зиждется на библиотеках/модулях/классах/компонентах/блоках и в них освобождать память таки надо. Для С - если в пределах одного .c файла память выделялась, то где-то в этом-же файле освобождается.

2) просто культура - если прям следом со 100% уверенностью, в любос случае, не следует exit то память надо освобождать.

MKuznetsov ★★★★★
()

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

Sorcerer ★★★★★
()

valgrind

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

освобождение памяти избавит от багрепортов, если кто-то решит погонять программу под соответствующими утилитами.

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

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

предполагается, что не превратится

Вот только что тебя останавливает от того что бы таки освободить память?

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

next_time ★★★★★
() автор топика

Имеет. Так сделано, например, в qemu. Но делать так надо очень осторожно.

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

Ну не знаю, как по мне, это несоблюдение как минимум правил хорошего тона.

В ответ на основной вопрос - можно, но лично я бы, такое увидев расстроился, хотя кому какое дело до моей ронимой души :)

А если не секрет что за утилита?

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

Где-то читал историю, про то как отработавший 20 дней cp потом ещё более суток освобождал свою память перед завершением. Так и не дождались, прибили.

PolarFox ★★★★★
()

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

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

Так сделано, например, в qemu.

И в Chromium. И, возможно, в Firefox. У него в инструкциях предлагается собирать его для запуска под valgrind с особыми флагами, и это кроме отключения jemalloc.

i-rinat ★★★★★
()
Ответ на: комментарий от pon4ik

А если не секрет что за утилита?

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

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

valgrind корректно отрабатывает такие сценарии, если только специально --show-reachable=yes не указывать.

mix_mix ★★★★★
()

Перепись быдлокодеров итт.

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

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

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

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

Здесь уместно процитировать Линуса:

Bad programmers worry about the code. Good programmers worry about data structures and their relationships.

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

если твои структуры данных настолько запутанные,

как ещё представить произвольный граф с минимальным оверхедом по скорости и памяти?

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

Минимальный оверхед - почти всегда не самое лучшее решение (если только это не «илитный запил»). Скорость надо выигрывать на хороших и понятных алгоритмах. Не зацикливайся на преждевременной оптимизации.

mtk
()

«А может? Не советую. А вот это можно попробовать, выполняйте» типа того. В общем не надо на это рассчитывать ;) Не повторяйте дома.

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от mtk

Минимальный оверхед - почти всегда не самое лучшее решение

c++ для того и создан, чтобы обеспечивать минимальный оверхед

Скорость надо выигрывать на хороших и понятных алгоритмах

ок. как бы вы реализовали произвольный граф?

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

произвольный граф

произвольные графы бывают только в произвольных программах

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

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

Как бы я реализовал: хранить адреса нод в списке, при необходимости (в т.ч. при дебаге) - весь граф как на ладони. При очистке памяти - пройтись по списку.

mtk
()

Да. Видел такое в некоторых CGI приложениях.

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

Перепись быдлокодеров

И только дартаньяны делают так:

int main()
{
  int *p = malloc ....
  ....
  free(p);
  p = NULL;
  return 0;
}

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

произвольные графы бывают только в произвольных программах

что за бред? вот есть задача: построить произвольный граф для определённых расчётов. например, поиск оптимального пути на карте. граф произволен, т.к. существуют подземные переходы, мосты и пр., позволяющее рёбрам пересекаться.

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

в списке? это +16 байт на каждую ноду. учитывая, что размер ноды, как правило, небольшой, получаем оверхед на память порядка 10-30%.

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

лучше, с этой точки зрения — массив, но при необходимости расширения графа расширение массива станет накладной операцией.

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

учитывая, что размер ноды <...> небольшой

В таком случае всё равно будет лучше запилить свой slab-like аллокатор. А когда ты его запилишь, освобождение памяти станет тривиальным — просто грохнуть всю созданную арену (она же «кэш», в терминах вики).

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 2)
Ответ на: комментарий от next_time

Прочитал, не нашел ответа на свой вопрос. Весь тред просто кричит о том, что это целенаправленная стрельба в ногу.

buddhist ★★★★★
()

Нет. За это надо отдавливать пальцы. Сам себе вероятные ошибки пишешь.

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

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

anonymous
()

Нет смысла освобождать память перед завершением программы — второе включает в себя первое в любой ОС.

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

в списке? это +16 байт

+8, т.к. sizeof(ptrdiff_t)==8 или 4. Ну и список пригодится для многого другого, помимо удаления.

например, поиск оптимального пути на карте

и как ты будешь искать «путь до музея», если не можешь получить список музеев?

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

Нет смысла освобождать память перед завершением программы — второе включает в себя первое в любой ОС.

смысл в том, что ПЕРЕД завершением программы _ничего_ нельзя будет дописать дополнительно.

Обычный говнокод у тебя получится, который write only.

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

комментировать некомпетентных дураков - это ведь так занимательно

понимаю, что чувствуют коментаторы российского футбола

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

смысл в том, что ПЕРЕД завершением программы _ничего_ нельзя будет дописать дополнительно.

Это не просто тупорылый высер анскильной обезьяны, это несвязный бред шизоида. Расскажи, в чем СМЫСЛ? ПЕРЕД завершением программы что-то дописывать. И почему это нельзя будет сделать. И причем тут ридонли, как это затрудняет чтение, макака?

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

Расскажи, в чем СМЫСЛ?

ты всё равно не поймёшь. Иди дальше float'ы складывай друг с другом, и радуйся, как оно быстро в SSE получается, скильный ты наш…

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

Нет, я имел в виду односвязный список, который хранит указатель на последующий элемент списка + указатель, собственно, на данные. выходит 2*8 = 16, байт. emulek

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

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

комментаторы футбола хотя-бы правила футбола знают, в отличие от тебя.

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

Нет, я имел в виду односвязный список, который хранит указатель на последующий элемент списка + указатель, собственно, на данные. выходит 2*8 = 16

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

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