Автор Тема: Говнокод  (Прочитано 15633 раз)

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Говнокод
« Ответ #30 : Июнь 14, 2012, 09:05:00 am »
Наткнулся на примерно такой код для ЧЯ:
TYPE
  Item = POINTER TO ItemDesc;
  ItemDesc = RECORD
    l, r : Item;
    v : INTEGER;
  END;

PROCEDURE Do* =
VAR
Comp: Item;
BEGIN
NEW ( Comp );
Comp.l := Comp;
Comp.r := Comp;
END;
Вопрос к знатокам ЧЯ, что произойдёт с экземпляром Item после выхода из Do(), как его GC обработает такие ссылки?

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Говнокод
« Ответ #31 : Июнь 14, 2012, 09:39:10 am »
Вопрос к знатокам ЧЯ, что произойдёт с экземпляром Item после выхода из Do(), как его GC обработает такие ссылки?
Очень странный вопрос. В Блэкбоксе настоящий сборщик мусора, зацикленность ссылок ему глубоко безразлична.

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Говнокод
« Ответ #32 : Июнь 14, 2012, 10:29:47 am »
Настоящий сборщик мусора это хорошо, но, вот есть, к примеру, двусвязный список, с элементами вышеуказанной структуры и что, в методе Clear этот список и расцеплять не надо? Почему там стоит только items := NIL?

PROCEDURE (l: List) Clear*;
BEGIN
  l.items := NIL;
END Clear;

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

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

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Говнокод
« Ответ #33 : Июнь 14, 2012, 11:14:44 am »
Если бы это был односвязный список, то всё понятно, этого достаточно, хотя я бы всё равно пробежался по списку и расцепил элементы - всё gc работы меньше
Не факт. Это зависит от типа GC. Это было бы преждевременной оптимизацией иногда приводящей к излишним тормозам на пустом месте (удаление списка не O(1) а O(n)). А если список бесконечный…
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Говнокод
« Ответ #34 : Июнь 14, 2012, 11:46:02 am »
Не факт. Это зависит от типа GC. Это было бы преждевременной оптимизацией иногда приводящей к излишним тормозам на пустом месте (удаление списка не O(1) а O(n)). А если список бесконечный…
Ну, если элементов миллионы, то, видимо, просядет существенно, с другой стороны, несвоевременное освобождение памяти занятой, по сути, мусорными объектами, тоже не есть гут, в любом случае, хоть ручное, хоть автоматическое разъединение такого количества элементов займет время. Другое дело, как его потратить.
Может вообще лучше вместо списков массивы использовать, так опять-же, если элементов миллионы и в массиве указатели, то всё равно ссылки инициализировать придётся.
Сергей Губанов, вроде, углубленно занимался изучением и ваянием GC, может он чего по этому поводу прояснит.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Говнокод
« Ответ #35 : Июнь 14, 2012, 11:50:25 am »
Настоящий сборщик мусора это хорошо, но, вот есть, к примеру, двусвязный список, с элементами вышеуказанной структуры и что, в методе Clear этот список и расцеплять не надо? Почему там стоит только items := NIL?

PROCEDURE (l: List) Clear*;
BEGIN
  l.items := NIL;
END Clear;

Если бы это был односвязный список, то всё понятно, этого достаточно, хотя я бы всё равно пробежался по списку и расцепил элементы - всё gc работы меньше - но список-то двусвязный, как gc эту гадость разрулит? Никак.
Проблема, которую Вы имеете в виду, может случиться в каком-нибудь питоне, где вместо сборщика мусора идёт просто подсчёт ссылок. там да, зацикленный список может остаться мусором в памяти.
Сборщик мусора же смотрит, остались ли у самой программы ссылки на объект, если есть хоть одна живая ссылка, то объект остаётся в памяти, если же у программы живых ссылок уже нет (сделали l.items := NIL;), то этот объект является мусором и уничтожается сборщиком...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Говнокод
« Ответ #36 : Июнь 14, 2012, 02:00:05 pm »
Если бы это был односвязный список, то всё понятно, этого достаточно, хотя я бы всё равно пробежался по списку и расцепил элементы - всё gc работы меньше - но список-то двусвязный, как gc эту гадость разрулит? Никак.
Алгоритм сборки мусора:
1) Пройтись по всем используемым блокам памяти и отметить их флагом "не используется".
2) Пройтись по всем достижимым указателям на объекты и перепометить блоки памяти в которых они размещены флагом "используется".
3) Утилизировать блоки памяти помеченные флагом "не используется".

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

Однако есть одно исключение.

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

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

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Говнокод
« Ответ #37 : Июнь 14, 2012, 02:12:34 pm »
Сергей Губанов, вроде, углубленно занимался изучением и ваянием GC
Да нет, я почти наоборот, я занимался тем как бы написать программу на C# так чтобы спрятать от GC объекты (на массивах структур), чтоб GC как можно меньше вреда причинял то и дело бегая по ним. Он же бегает только по указателям. Нет указателей - нет вреда от GC. Размещаешь объекты на массивах структур, а в роли указателей используешь индексы массивов, все дела.

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Говнокод
« Ответ #38 : Июнь 11, 2013, 06:37:04 am »
Сборщик мусора Блэкбокса в куче работает точно, но консервативен на стэке. Поскольку в рассматриваемом примере список в куче, то в Блэкбоксе бессмысленно вручную расцеплять элементы двусвязного списка при удалении всего усписка.
Наконец-то, мои руки-ковырялки добрались до сборщика мусора. Ну что сказать, в результате экспериментов, я пришел к выводу, что в Оберонах (по крайней мере в имеющейся у меня версии компилятора/рантайма) имеет смысл для списков, массивов указателей и вообще для динамических(ссылочных) аккуратно обнулять указатели, у всех элементов. Т.е. ссылочные типы должны иметь финализаторы, в которых выполняется вся эта грязная работа по расщеплению списков, очистке массивов указателей и тд). Потому что это все равно придётся сделать. Не финализатору, так сборщику мусора. Но если мы это делаем в финализаторе, то сборка мусора становится более управляемой, ровной, не возникает коллапсов, за счет того, что сборщику мусора не приходится бегать по существенно меньшим трассам.
В общем, помогая сборщику мусора, мы помогаем себе )

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Говнокод
« Ответ #39 : Июнь 11, 2013, 06:53:07 am »
Хотя, может я и не прав, пошел ещё тестировать

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Говнокод
« Ответ #40 : Июнь 11, 2013, 07:08:59 am »
Не, я не прав. На второй системе результаты противоположны. Ну то есть сам сборщик работает как работал, а вот производительность в целом понизилась.
Теперь надо понять, почему в первом случае результат был положителен.
Хотя, возможно, где-то ошибка в реализации СМ, или какая-то специфика, но память здесь перераспределялась более оптимально.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Говнокод
« Ответ #41 : Июнь 11, 2013, 08:17:23 am »
Наконец-то, мои руки-ковырялки добрались до сборщика мусора. Ну что сказать, в результате экспериментов, я пришел к выводу, что в Оберонах (по крайней мере в имеющейся у меня версии компилятора/рантайма) имеет смысл для списков, массивов указателей и вообще для динамических(ссылочных) аккуратно обнулять указатели, у всех элементов. Т.е. ссылочные типы должны иметь финализаторы, в которых выполняется вся эта грязная работа по расщеплению списков, очистке массивов указателей и тд). Потому что это все равно придётся сделать. Не финализатору, так сборщику мусора. Но если мы это делаем в финализаторе, то сборка мусора становится более управляемой, ровной, не возникает коллапсов, за счет того, что сборщику мусора не приходится бегать по существенно меньшим трассам.
В общем, помогая сборщику мусора, мы помогаем себе )

Для чего нужен сборщик мусора? Именно для того что бы нам, простым пользователям компилятора не приходилось ручками занулять эти самые ссылки на списки, массивы и прочее -- пусть от этого болит голова сборщика мусора и его автора...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…