Oberon space

General Category => Общий раздел => Тема начата: Губанов Сергей Юрьевич от Февраль 03, 2012, 09:32:47 am

Название: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Февраль 03, 2012, 09:32:47 am
Во время сборки мусора работа программы останавливается. Длительность паузы зависит от количества объектов и от объёма занимаемой памяти. Я измерил эту зависимость и построил графики, они там: Паузы в работе программы вызываемые сборщиком мусора .Net 3.5 (http://sergeygubanov.narod.ru/201202031205.htm) Длительность паузы может достигать 20 секунд если программой занято 8 Гб памяти и использовано более 100 миллионов объектов.

Можно обсудить границу применимости программ со сборщиком мусора в области мягкого реального времени. Например, мне на работе нужно чтобы время реакции программы не превышало 5 секунд. Мы пишем логику управления телефонной станцией. Пока программа занимает 1-2 гигабайта памяти (100'000 телефонов) -- всё нормально, а вот что делать если хочется 1'000'000 телефонов (> 5 гигабайтов) -- не очень понятно. В принципе ещё есть запас по рефакторингу, но он не бесконечный и рано или поздно мы всё таки упрёмся в непрошибаемую стену "мусорной паузы". Как её прошибать?

Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Peter Almazov от Февраль 03, 2012, 11:02:43 am
Я так понимаю, что 100 миллионов объектов - это НЕ мусорные объекты?
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: DIzer от Февраль 03, 2012, 11:35:20 am
В принципе ещё есть запас по рефакторингу, но он не бесконечный и рано или поздно мы всё таки упрёмся в непрошибаемую стену "мусорной паузы". Как её прошибать?
Писать внешний (относительно разрабатываемой вами системы) сервис управляющий мусорозборником - его цель -провоцировать стандартный мусоросборник на уборку таким образом,  что бы обеспечивалось приемлемое время реакции. это как самый дешевый вариант (я бы начал с исследования него)
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Февраль 03, 2012, 11:54:53 am
Я так понимаю, что 100 миллионов объектов - это НЕ мусорные объекты?
Да, это живые объекты.

Кстати, мусора у меня не очень много поскольку практически все объекты после "смерти" кэшируются для повторного использования (не кэширую объекты string и редко используемые). Но как бы ни было мало мусора, рано или поздно сборщик мусора всё равно полезет в третье поколение и вызовет паузу в работе программы.

провоцировать стандартный мусоросборник на уборку
А что это даёт? Возможно это как-то отсрочивает сборку в третьем поколении, но не ликвидирует же её вовсе. Хочется чтобы программа вообще-вообще-совсем-никогда не "подвисала" более чем на 5 секунд (даже ценой некоторой потери производительности).
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: DIzer от Февраль 03, 2012, 11:58:28 am
А что это даёт? Возможно это как-то отсрочивает сборку в третьем поколении, но не ликвидирует же её вовсе. Хочется чтобы программа вообще-вообще-совсем-никогда не "подвисала" более чем на 5 секунд (даже ценой некоторой потери производительности).
Это  и дает - сервис ДОЛЖЕН обеспечивать это свойство (период работы вашей системы с задержками не более 5 секунд).
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Февраль 03, 2012, 12:11:40 pm
сервис ДОЛЖЕН обеспечивать это свойство
Я не понимаю. Как?
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: DIzer от Февраль 03, 2012, 12:16:09 pm
сервис ДОЛЖЕН обеспечивать это свойство
Я не понимаю. Как?
Дробя все время штатной работы вашей системы на участки , перерыв  между которыми составляет не более 5 секунд (время работы мусорозборника).
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Peter Almazov от Февраль 03, 2012, 12:36:36 pm
Да ничего это не даст, ему же все равно потребуется пройтись по 100 000 000 объектов. А дробить-то просто - вызывай GC.Collect() хоть каждую секунду.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Geniepro от Февраль 03, 2012, 01:03:45 pm
В таких задачах надо что-то типа такого использовать:
www.usenix.org/event/vm04/wips/goh.pdf
"A Real-Time Garbage Collector for Embedded Applications in CLI"

http://research.microsoft.com/apps/video/dl.aspx?id=103698
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: DIzer от Февраль 03, 2012, 01:26:52 pm
Да ничего это не даст, ему же все равно потребуется пройтись по 100 000 000 объектов. А дробить-то просто - вызывай GC.Collect() хоть каждую секунду.
Это если она одна , а если их будет 10 (и в каждой по 100000) обьектов?
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: vlad от Февраль 03, 2012, 06:44:54 pm
Можно обсудить границу применимости программ со сборщиком мусора в области мягкого реального времени. Например, мне на работе нужно чтобы время реакции программы не превышало 5 секунд. Мы пишем логику управления телефонной станцией. Пока программа занимает 1-2 гигабайта памяти (100'000 телефонов) -- всё нормально, а вот что делать если хочется 1'000'000 телефонов (> 5 гигабайтов) -- не очень понятно. В принципе ещё есть запас по рефакторингу, но он не бесконечный и рано или поздно мы всё таки упрёмся в непрошибаемую стену "мусорной паузы". Как её прошибать?

Трудно что-то придумать без погружения в специфику... Но чисто из общих соображений: нельзя ли все эти гигабайты побить на отдельные процессы (по диапазонам номеров или по характеру выполняемой работы). В таком случае сборка будет проходить параллельно и с меньшими задержками. Кроме того, возможно эффективнее окажется отключить сборку вообще, а просто перезапускать процесс через какое-то время.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Февраль 04, 2012, 05:54:15 pm
Разделение на несколько процессов (каждый < 2 Гб) конечно решило бы проблему пауз GC, но это очень неудобно по бизнес логике. Удобно использовать одну структуру данных (на несколько гигабайтов).
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: vlad от Февраль 04, 2012, 06:43:59 pm
Разделение на несколько процессов (каждый < 2 Гб) конечно решило бы проблему пауз GC, но это очень неудобно по бизнес логике. Удобно использовать одну структуру данных (на несколько гигабайтов).

Ну вот так иногда бывает, что особенности платформы оказывают влияние на архитектуру и прочую бизнес логику :)
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Peter Almazov от Февраль 04, 2012, 07:03:06 pm
Проблема-то общая для всех языков со сборкой мусора.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Berserker от Февраль 04, 2012, 07:21:16 pm
В сообщении речь идёт о времени реакции. Нужно размазать одну большую сборку (мусор копится постепенно, объекты кэшируются) на несколько сессий. Если вызывать через определённый интервал GC.Collect, время сборки мусора уменьшится и реакция будет обеспечена.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Февраль 04, 2012, 07:54:13 pm
Если вызывать через определённый интервал GC.Collect, время сборки мусора уменьшится и реакция будет обеспечена.
Максимальная продолжительность паузы зависит от количества живых объектов в последнем поколении (их надо все обойти) и занимаемого ими объёма памяти (если делать дефрагментацию), но не зависит от количества умерших объектов. Если вручную вызывать System.GC.Collect(), то мусора станет меньше, но количество живых объектов не изменится, а значит не изменится и продолжительность паузы.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Peter Almazov от Февраль 05, 2012, 06:15:52 am
Если памяти очень много, то можно подумать о такой идеологии.
Поделить память, скажем, пополам, в каждой половине запустить задание, из которых только одно активно работает. Мусор не собирать вообще или собирать малой кровью, без уплотнения. Когда активное задание исчерпает всю свою память - переключиться на другое. А первое уничтожить, освободив всю память разом. Потом снова запустить его как горячий резерв.
В общем, суть в том, чтобы мусором считать большой кусок памяти целиком.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Февраль 05, 2012, 06:06:03 pm
В принципе ещё есть запас по рефакторингу
Сейчас обдумываю как для перманентного текста (телефонный номер, логин и прочие вечные текстовые идентификаторы) уйти от использования System.String. Так можно дёшево и сердито избавиться от большого количества объектов.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Февраль 05, 2012, 06:15:53 pm
Между прочим, вот поэтому для, систем массового обслуживания, в том числе и class 5, принято таки использовать erlang.

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

Во-вторых, там сборщик мусора всегда гарантированно работает линейное время (от размера кучи).

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

PS. А вообще, для хренения таких вот больших объемов данных (особенно вечных) обычно используют какую-нибудь no-sql базу данных. В простейшем случае мнезию (mnesia) (для ерланга).
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: alexus от Февраль 06, 2012, 04:10:09 am
Во-вторых, там сборщик мусора всегда гарантированно работает линейное время (от размера кучи).
Кто бы мне пояснил... в чём радость от использования сборщиков мусора?..
К примеру, научили школяра/студента писать на oberon, где встроенный сборщик мусора. Устроился этот бывший школяр на работу программистом, а там на C++ пишут или на Delphi... И начались проблемы с протечками. Не лучше ли прививать культуру работы с памятью. Нет же в этом ничего заумного и трудного. Меня не напрягает для программ, где используется много объектов, расписывать карту памяти... это позволяет заблаговременно понять, что же и как, собственно, делается в программе... увидеть узкие места. Такие задачи никакой сборщик мусора за программиста не решит.
Другими словами, наличие сборщика мусора в среде разработки/языке я бы скорее оценил отрицательно... не говоря уже о тех проблемах (тормоза), которые поднял Сергей.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Февраль 06, 2012, 05:39:26 am
Во-вторых, там сборщик мусора всегда гарантированно работает линейное время (от размера кучи).
Кто бы мне пояснил... в чём радость от использования сборщиков мусора?..
Предлагаю про то, зачем же сборщик мусора вообще существует, продолжить тут: http://oberspace.dyndns.org/index.php/topic,175.0.html
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Geniepro от Февраль 06, 2012, 06:11:52 am
Кто бы мне пояснил... в чём радость от использования сборщиков мусора?..
К примеру, научили школяра/студента писать на oberon, где встроенный сборщик мусора. Устроился этот бывший школяр на работу программистом, а там на C++ пишут или на Delphi... И начались проблемы с протечками. Не лучше ли прививать культуру работы с памятью. Нет же в этом ничего заумного и трудного. Меня не напрягает для программ, где используется много объектов, расписывать карту памяти... это позволяет заблаговременно понять, что же и как, собственно, делается в программе... увидеть узкие места. Такие задачи никакой сборщик мусора за программиста не решит.
Другими словами, наличие сборщика мусора в среде разработки/языке я бы скорее оценил отрицательно... не говоря уже о тех проблемах (тормоза), которые поднял Сергей.
Для большинства задач сборщик мусора просто упрощает жизнь -- меньше головной боли, больше времени думать о задаче.
Вы ведь наверняка не расписываете цикл WHILE через машинные команды jmp и прочих branch. Используете привычную синтаксическую конструкцию, сахар.
Так и сборщик мусора тоже сахар, правда не синтаксический...

Ну, а такие экстремальные ситуации, как у Сергея, требуют нестандартных подходов...
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: alexus от Февраль 06, 2012, 07:20:55 am
Для большинства задач сборщик мусора просто упрощает жизнь -- меньше головной боли, больше времени думать о задаче.
Вот-вот... я именно к этому и сводил... Думать о задаче - это либо моделирование программы, либо её проектирование. А сборщик мусора "облегчает" (пока не буду убирать кавычки) кодирование... Другими словами, если не сваливать все этапы в одну кучу, то... жизненность GC становится вопросом.

Вы ведь наверняка не расписываете цикл WHILE через машинные команды jmp и прочих branch. Используете привычную синтаксическую конструкцию, сахар.
Промах. Вы приводите ссылку на наш сайт, а материалы, которые там лежат не читали (видимо). В этих материалах весь код представлен на 2-х языках... SQL и ассемблер. То есть, машинными кодами меня не напугаешь... :)

Ну, а такие экстремальные ситуации, как у Сергея, требуют нестандартных подходов...
Не такие уж это экстремальные ситуации... Когда программа анализирует производство, то имеем "матрицу" N * M (где M - количество операций, а M - количество партий). Для среднего по объёмам заказного производства имеем ту же, что и у Сергея, размерность. И число таких задач довольно велико, хотя они ещё далеки от того, чтобы стать массовыми.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Peter Almazov от Февраль 06, 2012, 09:20:07 am
Когда программа анализирует производство, то имеем "матрицу" N * M (где M - количество операций, а M - количество партий). Для среднего по объёмам заказного производства имеем ту же, что и у Сергея, размерность. И число таких задач довольно велико, хотя они ещё далеки от того, чтобы стать массовыми.
И что, программа не может подождать 10 сек?
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: alexus от Февраль 06, 2012, 09:34:16 am
Когда программа анализирует производство, то имеем "матрицу" N * M (где M - количество операций, а M - количество партий). Для среднего по объёмам заказного производства имеем ту же, что и у Сергея, размерность. И число таких задач довольно велико, хотя они ещё далеки от того, чтобы стать массовыми.
И что, программа не может подождать 10 сек?
А программа не ждёт... Ждут пользователи... результатов работы программы. У нас нет жёстких требований по времени, это не системы реального времени, ни системы массового обслуживания. Но по объёму данных примерный паритет с теми задачами, о которых говорил Сергей.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Geniepro от Февраль 06, 2012, 09:41:17 am
Вы ведь наверняка не расписываете цикл WHILE через машинные команды jmp и прочих branch. Используете привычную синтаксическую конструкцию, сахар.
Промах. Вы приводите ссылку на наш сайт, а материалы, которые там лежат не читали (видимо). В этих материалах весь код представлен на 2-х языках... SQL и ассемблер. То есть, машинными кодами меня не напугаешь... :)
Я скачивал статьи с вашего сайта, но руки не дошли прочесть, увы. По теме работы пока никак нет нужды.

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

Ну, а такие экстремальные ситуации, как у Сергея, требуют нестандартных подходов...
Не такие уж это экстремальные ситуации... Когда программа анализирует производство, то имеем "матрицу" N * M (где M - количество операций, а M - количество партий). Для среднего по объёмам заказного производства имеем ту же, что и у Сергея, размерность. И число таких задач довольно велико, хотя они ещё далеки от того, чтобы стать массовыми.

Ну у Вас же там в этих экономических задачах разные методы оптимизации есть, так и тут тоже надо оптимизировать...
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Peter Almazov от Февраль 06, 2012, 10:12:39 am
А программа не ждёт... Ждут пользователи... результатов работы программы. У нас нет жёстких требований по времени, это не системы реального времени, ни системы массового обслуживания. Но по объёму данных примерный паритет с теми задачами, о которых говорил Сергей.
Тогда и нет никаких проблем от наличия сборщика мусора. Наоборот, пользователи быстрее дождутся появления новых программ для решения новых задач.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Февраль 08, 2012, 10:34:01 am
А вот как решают эту проблему в Обероне (точнее, видимо, в Компонентном паскале):

Цитата: Илья Ермаков
...на Обероне возможно разрабатывать высоконагруженные приложения, вообще не использующие сборку мусора. Т.е. сборщик просто отключен. Объекты держатся в пулах - берутся из них и в них возвращаются. Двоичные данные (строки и др.) хранятся в спец. объектах, подобных File в памяти. Такое приложение выжирает под максимальной нагрузкой некоторый объём памяти (под всякие разные объекты), а затем эти объекты живут постоянно, крутятся в пулах.

Это возможно только при условии, что все компоненты не порождают при своей работе мусор.
"Идиллию" может обломать вот этот безобидный NEW, где-нибудь вызываемый раз в минуту, в модуле уважаемого Ивана Кузьмицкого, который он любезно опубликовал, а я, не проверив, использовал в своём нагруженном приложении :)

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

Если что, оригинал тут: http://forum.oberoncore.ru/viewtopic.php?p=70517#p70517

PS. Хотя я не очень понял при чем тут высоконагруженное нечто, ведь именно на производительность сборщик мусора в среднем не влияет (где-то с ним эффективней, где-то без него). Он гадит только в случае если нам нужен реалтайм. Таким образом, видимо следует заменить "высоконагруженное приложение" на "реалтайм приложение".
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: trurl от Февраль 08, 2012, 11:29:15 am
К примеру, научили школяра/студента писать на oberon, где встроенный сборщик мусора. Устроился этот бывший школяр на работу программистом, а там на C++ пишут или на Delphi... И начались проблемы с протечками.
Вероятность устоиться на работу, где пишут на C# или Java гораздо выше.  ;)
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Февраль 08, 2012, 12:47:37 pm
PS. Хотя я не очень понял при чем тут высоконагруженное нечто, ведь именно на производительность сборщик мусора в среднем не влияет (где-то с ним эффективней, где-то без него). Он гадит только в случае если нам нужен реалтайм.
Не только в реалтайме если речь о Блэкбоксе. В Блэкбоксе сборщик мусора не ранжирует объекты по поколениям, поэтому при большом количестве объектов он тормозит постоянно. Когда я сравнивал Блэкбокс с дотнетом, то обнаружил следующее. Допустим есть 5 миллионов фоновых объектов и 1000 объектов то и дело создаваемых и выбрасываемых в мусор. Дотнетная программа переместит 5М фоновых объектов в третье поколение и будет летать со скоростью света. А Блэкбокс вообще встанет колом, так как будет оббегать все 5'001'000 объектов каждый раз.

Справедливости ради, конечно, надо заметить, что при противоположной дисциплине удаления объектов, когда большое количество объектов удаляются по карусели дотнет окажется медленнее Блэкбокса. Сбор мусора в третьем поколении в дотнете при специально подобранных условиях может осуществлятся до трёх раз медленнее чем в Блэкбоксе (видимо из-за выполнения дефрагментации памяти).
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Romiras от Февраль 15, 2012, 01:52:51 pm
Модели утилизации динамической памяти (http://www.osp.ru/pcworld/2008/01/4794170/) (статья из Мир ПК , № 01, 2008)
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Февраль 22, 2012, 01:34:46 pm
А в .net только один тип сборщика мусора доступен? Просто когда у меня возникла подобная проблема в java, я просто включил инкрементальный сборщик мусора. В среднем нагрузка на процессор чуть повысилась, но паузы исчезли. Плюс в java есть еще и параллельный сборщик мусора (по крайней мере в java7).
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Valery Solovey от Февраль 22, 2012, 02:12:07 pm
А как переключать сборщик мусора?
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Февраль 22, 2012, 02:34:41 pm
А как переключать сборщик мусора?
http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#available_collectors.selecting

ну и вообще вся эта статья.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Февраль 22, 2012, 02:52:12 pm
Борьюсь с паузами уменьшая количество объектов видимых сборщику мусора.

Прячу объекты на массивах структур.

Миллионы строк загруженных из БД спрятал на больших массивах char[сегмент][смещение]. Вместо System.String для них использую 4-х байтовую структурку в которой закодировано сегмент-смещение начала "строки". Там первая буква -- длина строки, затем собственно содержимое. Когда кончается текущий сегмент создаю новый. Эти строки "вечные" -- их нельзя удалить. Поэтому они пригодны только для "вечных" данных -- как раз для содержимого БД.

Наблюдаемый прогресс в производительности программы радует  :) :) :)

С полиморфными объектами (с виртуальными процедурами) пока не придумал что делать. На массивах структур их спрятать от сборщика мусора не получится, так как для вызова виртуальной процедуры нужен настоящий сэйфный указатель.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Илья Ермаков от Февраль 24, 2012, 04:33:30 am
Можно перейти к своим указателям на полиморфные объекты след. вида:

TYPE
  Object = RECORD
    vt: ANYPTR;
    data: DataDesc
   END;

Имея obj: Object, можем вызвать какой-нибудь метод так:

obj.vt(приведение_к_абстрактному_типу-интерфейсу).vt.DoSomething(data, ....)
Т.е. динамических объектов будет существовать ровно по одному на каждый используемый в программе тип. Они будут просто "представителями" виртуальных таблиц.

Каждый тип имеет массив для хранения данных своих объектов. И data - это может быть, например, такой же сегмент-смещение, как и для Ваших строк.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Февраль 24, 2012, 12:18:10 pm
Можно перейти к своим указателям на полиморфные объекты след. вида:

TYPE
  Object = RECORD
    vt: ANYPTR;
    data: DataDesc
   END;
Только в vt надо бы не указатель, а тоже индекс в массиве виртуальных таблиц. Предполагается, что объектов Object миллионы и надо минимизировать количество указателей. Для сборщика мусора важно как количество объектов так и количество указателей. Даже если все N-миллионов указателей будут указывать на небольшое количество объектов, то всё равно сборщик мусора должен будет обойти все N-миллионов указателей. И на N-миллионных массивах структур в каждой структуре тоже не должно быть ни одного указателя, а то сборщик мусора будет на них лазить.

Хотя, честно говоря вот к такому:
obj.vt(приведение_к_абстрактному_типу-интерфейсу).vt.DoSomething(data, ....)
я поко не очень готов, а мои коллеги к такому готовы ещё меньше. Скорее всего полифорфные объекты прятать от сборщика мусора мы вообще не будем, пока хватит улучшений от упрятывания простых объектов.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Март 01, 2012, 12:18:55 pm
Кстати, можно ли смоделировать эту проблему/задачу в относительно маленьком куске кода для последующих экспериментов/бенчмарков? C одной стороны такой код должен быть достаточно большим и организован так, чтобы например cстатический и jit анализатор кода в той же жабе не выкинул бы этот код целиком (просто потому что он ничего полезного не делает - побочных эфектов нет, значит код не нужен, циклы можно не крутить). C другой стороны, какой-нибудь IO и прочие бантики (которые приближают эту модель к реальной моделируемой задаче) не должны вносить значимый вклад в получаемую картину.

Просто хочется посмотреть как подобное выглядит на той же жабе (с разными сборщиками мусора), Go и D. И какие пути решения проблемы существуют там.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Март 01, 2012, 12:23:15 pm
Миллионы строк загруженных из БД спрятал на больших массивах char[сегмент][смещение]. Вместо System.String для них использую 4-х байтовую структурку в которой закодировано сегмент-смещение начала "строки". Там первая буква -- длина строки, затем собственно содержимое. Когда кончается текущий сегмент создаю новый. Эти строки "вечные" -- их нельзя удалить. Поэтому они пригодны только для "вечных" данных -- как раз для содержимого БД.

Позавчера написал структуру UnmanagedString для ручной работы со строками. Её размер 4 байта -- "индекс" в массиве. Буквы лежат в большом массиве char[сегмент][смещение]. Новые сегменты добавляю по мере надобности. Размер одного сегмента выбрал в 4 мегабуквы, то есть в 8 мегабайтов. Масимальная длина строки = 2^16 - 1 букв. Аллокатор памяти самый простой -- на основе пулов блоков памяти.  Свободные блоки памяти никогда не сливаются друг с другом и обратно в операционную систему не возвращаются. Это самый быстрый менеджер памяти: время создания/удаления объекта O(1).  Выравнивание блоков памяти выбрал в 4 буквы (8 байтов). Односвязные списки (стэки) свободных блоков организуются как в менеджере памяти Delphi с помощью размещения "индексов" в самих же свободных блоках (ведь они же свободны!!!) так что память расходуется максимально экономно.

Вчера в одной подсистеме программы заменил string на UnmanagedString -- эффект впечатлил. Если раньше график расхода памяти в зависимости от времени выглядел как бешенная пила, то теперь стала ровная горизонтальная линия -- мусора не генерируется.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Март 01, 2012, 12:26:00 pm
Вчера в одной подсистеме программы заменил string на UnmanagedString -- эффект впечатлил. Если раньше график расхода памяти в зависимости от времени выглядел как бешенная пила, то теперь стала ровная горизонтальная линия -- мусора не генерируется.
Да, я вчера тоже впечатлился (я видел тот график, точнее, сколь я помню, там было всего 6 графиков - по три графика на каждую из двух подсистем (три графика - три варианта работы с памятью)).
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Март 01, 2012, 12:41:36 pm
Кстати, можно ли смоделировать эту проблему/задачу в относительно маленьком куске кода для последующих экспериментов/бенчмарков?

Конечно можно. Я так и делал. Запускаешь два потока. Один поток мусорит. Второй поток делает Sleep(1) и измеряет сколько времени он на самом деле проспал, максимальное время спячки и будет максимальной паузой GC.

Программа работает очень долго, для построения одной "линии" я оставлял её на ночь:

namespace TestGCPause
{
   class Program
   {
      static void Main (string[] args)
      {
         using (OneTest x = new OneTest())
         {
            for (uint i = 1; i < 100; i++) // вычисляем 100 точек для одной "линии"
            {
               System.GC.Collect();
               x.Run((1000000 * i)*4);
            }
         }
      }
   }

   public sealed class OneTest: System.IDisposable
   {
      private bool isDisposed;
      private double maxPause;

      public OneTest ()
      {
         System.Threading.Thread thread = new System.Threading.Thread(this.GCLoop);
         thread.Start();
      }

      public void Run (uint objectCount)
      {
         this.maxPause = 0;
         long m0 = System.GC.GetTotalMemory(true);
         this.maxPause = 0;
         byte[][] a = new byte[objectCount][];
         ulong k = 127837817; // это быстрый генератор случайных чисел
         const ulong dk = 3746123567;
         for (int i = 0; i < 10; i++)
         {
            for (int j = 0; j < objectCount; j++)
            {
               k = k + dk;
               ulong size = 16 + (k % (64 - 16));
               //ulong size = 64 + (k % (256 - 64));
               //ulong size = 256 + (k % (1024 - 256));
               byte[] x = new byte[size];
               x[k % size] = (byte)k;
               a[k % objectCount] = x;
            }
         }
         long m1 = System.GC.GetTotalMemory(true);
         System.Console.Write("{" + (m1 - m0) + ", " + this.maxPause + "},");
         System.GC.KeepAlive(a);
      }

      private void GCLoop () // Этот поток измеряет паузы
      {
         while (!this.isDisposed)
         {
            System.DateTime t0 = System.DateTime.UtcNow;
            System.Threading.Thread.Sleep(1);
            System.DateTime t1 = System.DateTime.UtcNow;
            double dt = (t1 - t0).TotalSeconds;
            if (this.maxPause < dt)
            {
               this.maxPause = dt;
            }
         }
      }

      public void Dispose ()
      {
         this.isDisposed = true;
      }
   }
}
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Март 01, 2012, 01:03:39 pm
Программа работает очень долго, для построения одной "линии" я оставлял её на ночь
Здесь я опубликовал вариант печатающий результат в консоль. Если собираетесь запускать её на ночь, то лучше пишите результат в файл (а то если кончится память программа упадёт и результат многочасовых вычислений пропадёт).
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Март 01, 2012, 01:15:54 pm
Программа работает очень долго, для построения одной "линии" я оставлял её на ночь
Здесь я опубликовал вариант печатающий результат в консоль. Если собираетесь запускать её на ночь, то лучше пишите результат в файл (а то если кончится память программа упадёт и результат многочасовых вычислений пропадёт).
Ну, это ж одно и то же, просто перенаправлю выход stdout в файла и все. Типа "mono test.exe > logfile"
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Март 01, 2012, 01:33:03 pm
А System.GC.Collect() обязательно вызывать? Оно ж во-первых не везде будет доступно, а во-вторых в случае инкрементального сборщика мусора особого смысла не имеет.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Март 01, 2012, 02:13:51 pm
Прочитал исходник, похоже это немного не то что я хотел. То есть это не моделирование задачи, а измерение конкретно сколько займет сборка мусора (разовая) когда намусорили вот столько-то (судя по System.GC.KeepAlive(a); ).

Я же хотел смоделировать предметную область где вырастает эта проблема.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Апрель 12, 2012, 02:38:17 pm
В одной из программ разместил (практически все) объекты на массивах структур.

Расход памяти до и после:

(http://sergeygubanov.narod.ru/allocationOnArray.png)
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Peter Almazov от Май 03, 2012, 03:31:35 pm
Полезная книга про работу с памятью в .NET от RED-GATE:
Under the Hood of .NET Memory Management

Часть 1  ftp://support.red-gate.com/ebooks/under-the-hood-of-net-memory-management-part1.pdf
Часть 2  http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/learning-memory-management/memory-management-gotchas

Статья на хабре http://habrahabr.ru/post/141032/
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Август 14, 2012, 07:28:36 pm
На хабре появилась статья про потроха GC в .net современных версий: http://habrahabr.ru/post/149584/
Ну и про то как там бороться с паузами. Вдруг кому пригодится...
(в приложении к тем задачам что решаются у нас в конторе, насколько я понимаю, не слишком это все будет актуально, ибо это мелкософтоспецифично, а под mono все иначе).
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Август 14, 2012, 08:27:47 pm
В Mono есть ряд багов из-за которых большая программа со структурами вида

public struct MyOutOfHeapObject
{
  private uint handle;

  // далее геттеры-сеттеры перенаправляющие управление в реальный объект по handle
}

работает не правильно (порча памяти). Засада в том, что на простых примерах эти баги не воспроизводятся, так что практически нереально на этот баг пожаловаться разработчикам Mono.

Ждал несколько месяцев, надеялся в новых версиях Mono они эту беду сами обнаружат и победят. Зря. Они о ней видимо не знают до сих пор.

В последний день перед уходом в отпуск переписал программу чуток по-другому. Спрятал хэндлы объектов внутрь целочисленных енумов:

public static class MyOutOfHeapObject
{
  public enum Handle: uint
  {
      NULL = 0
  }

  // далее статические геттеры-сеттеры перенаправляющие управление в реальный
  // объект по енумному-целочисленному handle
}

В результате под Mono программа заработала правильно.

Правда дико неудобно стало писать. Вместо цепочки разыменования "указателей" навроде:

Gamma g = ...;
c = g.A.B.C;
g.A.B.C = c;

теперь приходится писать как-то так:

Gamma.Handle g = ...;
c = Beta.GetC(Alpha.GetB(Gamma.GetA(g)));
Beta.SetC(Alpha.GetB(Gamma.GetA(g)), c);
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Август 14, 2012, 08:33:11 pm
Ждал несколько месяцев, надеялся в новых версиях Mono они эту беду сами обнаружат и победят. Зря. Они о ней видимо не знают до сих пор.
А почему ты им не отписал в багзиллу (или что у них там вместо)?
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Август 14, 2012, 08:52:39 pm
А почему ты им не отписал в багзиллу (или что у них там вместо)?
А что я им напишу? Доктор, у меня в подполе подпольный стук? Попытка воспроизвести баг на маленьком примере не увенчалась успехом. Воспроизводится только в большой программе.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Август 14, 2012, 08:54:08 pm
На хабре появилась статья про потроха GC в .net современных версий: http://habrahabr.ru/post/149584/
По моему эта статья была написана автоматическим бредогенератором.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Август 14, 2012, 08:59:36 pm
А почему ты им не отписал в багзиллу (или что у них там вместо)?
А что я им напишу? Доктор, у меня в подполе подпольный стук? Попытка воспроизвести баг на маленьком примере не увенчалась успехом. Воспроизводится только в большой программе.
Эмм.. А это на каком сборщике мусора (из вроде у моно две штуки на выбор).
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey от Август 14, 2012, 09:00:02 pm
На хабре появилась статья про потроха GC в .net современных версий: http://habrahabr.ru/post/149584/
По моему эта статья была написана автоматическим бредогенератором.
А в чем там бред? (я еще не осилил эту простыню, но картинки вроде есть :-) )
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Август 15, 2012, 08:01:51 am
Эмм.. А это на каком сборщике мусора (из вроде у моно две штуки на выбор).
На дефолтном, но GC вроде не при чём.

Один баг такой. При передаче по значению структуры содержащей один лишь uint в процедуру в этом uint-е может оказаться мусор. Это вроде как происходит только при первом вызове процедуры, а при последующих вызовах вроде всё нормально (при первом вызове в JIT-системах обычно вызывается заглушка JIT компилятора, который уже генерирует реальный код для этой процедуры). Если добавить в эту структуру ещё один uint, то мусор может оказаться в первом поле структуры. То есть ошибка видимо с вычислением адреса структуры переданной через стек.

Другой баг такой. При присваивании одному структурному полю структуры
x.a = a; // a - другая структура
происходит порча следующего(щих) поля(ей) этой структуры. Структура должна быть большой и сложной (содержать другие структуры). То есть ошибка опять с вычислением адреса. Возможно эта ошибка связана с неправильным выравниванием полей по адресам кратным 8, 4 и т. п. так как если поля переупорядочить чтобы выравнивание стало тривиальным этот баг пропадает.

Есть ещё другие баги которые нам не удалось локализовать: программа просто работает не правильно и всё тут (а под Windows она же (без перекомпиляции) работает правильно).

На простых примерах, естественно, ничего из этого не воспроизводится.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Июнь 11, 2013, 01:04:50 pm
Я перешёл на новый уровень игры в прятание объектов от сборщика мусора :)

Написал свою обёртку UnmanagedMemory над стандартным System.Runtime.InteropServices.Marshal.AllocHGlobal / FreeHGlobal:

void* UnmanagedMemory.Allocate(int size);
void UnmanagedMemory.Free(void* pointer);

И размещаю объекты в стиле Си, благо определённое подмножество языка Си является подмножеством языка C#.

Свою обёртку пришлось написать потому, что под Mono Marshal.AllocHGlobal и Marshal.FreeHGlobal работают медленнее чем у Микрософта да ещё и можно сказать, что практически не параллельные.

Теперь моя UnmanagedString реализована как структура внутри которой лежит указатель int* p. При этом p[0] - длина строки, p[1] - счётчик ссылок, а начиная с адреса (char*)p + 4 лежат буквы char (char в C# двухбайтовый).

Всё как бы lock-free, реализовано на System.Threading.Interlocked.Exchange / Increment / Decrement.


Кстати, скорости работы стандартного аллокатора System.Runtime.InteropServices.Marshal.AllocHGlobal / FreeHGlobal если его мучить в один или в десять потоков выделяя куски памяти случайного размера 1..1024 байтов:

Microsoft .Net 4.5, Windows 7, Core i7 2600K, 3.4-3.8 GHz, DDR3 1600 MHz
Thead count =  1, rate =  6’066’457 (alloc+free) / sec
Thead count = 10, rate = 28’922’333 (alloc+free) / sec

Mono 2.10.8.1 (Debian 2.10.8.1-8), Core i7 950, 3.0-3.13 GHz, DDR3 1066 MHz
Thead count =  1, rate =  3’943’747 (alloc+free) / sec
Thead count = 10, rate =  6’112’558 (alloc+free) / sec

Моя реализация под Windows работает со скоростью 28-29 миллионов в секунду во много потоков и где-то 14-16 миллионов в секунду в один-два потока.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Октябрь 18, 2013, 08:54:44 am
В общем, сбылась мечта. Мой модуль управления телефонной станцией теперь может обслуживать миллион абонентов не только под Windows, но и под Mono. Многие критически важные (по производительности) объекты разместил в неуправляемой памяти в Си-стиле. Те объекты которые ещё не разместил не очень-то и тормозят, по крайней мере для миллиона хватает (тормозит где-то на трёх миллионах абонентах).

Правда Mono взятая "из коробки" для этого не годится (падает). Mono нужно компилировать самому вот так:

tar xvfz mono-2.10.8.1.tar.gz
./configure
./configure --with-gc=sgen --with-large-heap=yes
make
make install

Далее программы запускать с опцией --gc=sgen

mono --gc=sgen имявашейпрограммы.exe

------------------------------------------------------------------------------------------------------------


На этом моя борьба со сборщиком мусора закончена. Я меняю место работы. Работу я выполнял фактически сишную, а оплачивалась она по сишарповски. Исправляя этот дисбаланс, с понедельника перехожу на новое место работы, на котором буду программировать на C/C++.

Как говориться, это был номер только для профессиональных каскадёров, не пытайтесь повторить это дома. Мой эксперимент показал, что да, C# позволяет таки разогнаться до скорости света если разместить объекты в неуправляемой памяти, но едва ли вам будут платить за эту работу столько же как C/С++ программисту.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Geniepro от Октябрь 18, 2013, 10:50:01 am
... перехожу на новое место работы, на котором буду программировать на C/C++.

Эх, а какие когда-то были дифирамбы оберонам )))
Жизнь всё раставила по своим местам )))
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey_u от Октябрь 18, 2013, 11:27:43 am
В общем, сбылась мечта. Мой модуль управления телефонной станцией теперь может обслуживать миллион абонентов не только под Windows, но и под Mono. Многие критически важные (по производительности) объекты разместил в неуправляемой памяти в Си-стиле. Те объекты которые ещё не разместил не очень-то и тормозят, по крайней мере для миллиона хватает (тормозит где-то на трёх миллионах абонентах).

Правда Mono взятая "из коробки" для этого не годится (падает). Mono нужно компилировать самому вот так:

tar xvfz mono-2.10.8.1.tar.gz
./configure
./configure --with-gc=sgen --with-large-heap=yes
make
make install

Далее программы запускать с опцией --gc=sgen

mono --gc=sgen имявашейпрограммы.exe
То есть там по сути получается небезопасное полностью ручное управление памятью в стиле Си? (не С++ - там принято все же полуавтоматическое)

Цитировать
На этом моя борьба со сборщиком мусора закончена. Я меняю место работы. Работу я выполнял фактически сишную, а оплачивалась она по сишарповски. Исправляя этот дисбаланс, с понедельника перехожу на новое место работы, на котором буду программировать на C/C++.

Как говориться, это был номер только для профессиональных каскадёров, не пытайтесь повторить это дома. Мой эксперимент показал, что да, C# позволяет таки разогнаться до скорости света если разместить объекты в неуправляемой памяти, но едва ли вам будут платить за эту работу столько же как C/С++ программисту.
Ну так на шарпе управлять памятью действительно странно - преимуществ шарпа почти и не остается. То есть то же самое на С++ написать удобней можно.

А по поводу зарплат, если верить вот этому: http://habrahabr.ru/company/it_dominanta/blog/147866/ то разница средних зарплатах между С++ программером и С# программером в общем то и нет. А вот дисперсия да, у C++ больше (за счет большей применимости языка - больше разных задач за которые очень по разному платят, как очень мало так и весьма прилично).

А вот где зарплаты действительно выше, и куда уходят шарписты естественным образом если хотят денег - то это java. Точнее - j2ee или java+highload (возможно тоже частично на j2ee).

Плюс, учти что у тебя еще и эффект от смены работы имеется - при переходе с места на место зарплата растет скачкообразно. Если я сменю место работы, то у меня зарплата скорее всего увеличится в полтора-два раза. Хотя на каких языках я программировал, на тех и буду программировать.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: kkk от Октябрь 18, 2013, 11:43:04 am
... перехожу на новое место работы, на котором буду программировать на C/C++.

Эх, а какие когда-то были дифирамбы оберонам )))
Жизнь всё раставила по своим местам )))
Колбасная эмиграция, она такая.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: Губанов Сергей Юрьевич от Октябрь 18, 2013, 12:39:27 pm
То есть там по сути получается небезопасное полностью ручное управление памятью в стиле Си?
Не очень понял вопрос. Объекты я кэшировал для повторного использования задолго до того как стал их размещать сначала на массивах структур, а потом и вовсе в неуправляемой памяти. То есть временем жизни объектов я управлял вручную очень давно. И это не имеет отношения к Си. Размещение объектов на массивах структур привело к тому, что GC перестал видеть эти объекты, и перестал делать паузы в работе программы. Размещение объектов в неуправляемой памяти привело к ускорению работы: доступ по указателям всё же быстрее чем по индексам в двумерном массиве (двумерный так как нужна страница+смещение). Но теперь да, конечно, шаг вправо, шаг влево - порча памяти - это как в Си.

А по поводу зарплат, если верить вот этому: http://habrahabr.ru/company/it_dominanta/blog/147866/ то разница средних зарплатах между С++ программером и С# программером в общем то и нет. А вот дисперсия да, у C++ больше
Вот поэтому надо ориентироваться не на среднюю, а на максимальную - каков потолок.

Кстати, в указанной тобой статье неверные данные по потолку зарплаты для С++ по Нижнему Новгороду. Там где я буду работать потолок зарплат выше, такой же высокий как для Java. То есть идти переучиваться в Java программиста только лишь из-за денег для меня смысла нет.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey_u от Октябрь 18, 2013, 12:43:31 pm
То есть там по сути получается небезопасное полностью ручное управление памятью в стиле Си?
Не очень понял вопрос. Объекты я кэшировал для повторного использования задолго до того как стал их размещать сначала на массивах структур, а потом и вовсе в неуправляемой памяти. То есть временем жизни объектов я управлял вручную очень давно. И это не имеет отношения к Си. Размещение объектов на массивах структур привело к тому, что GC перестал видеть эти объекты, и перестал делать паузы в работе программы. Размещение объектов в неуправляемой памяти привело к ускорению работы: доступ по указателям всё же быстрее чем по индексам в двумерном массиве (двумерный так как нужна страница+смещение). Но теперь да, конечно, шаг вправо, шаг влево - порча памяти - это как в Си.
Я имел ввиду, что теперь там нет ни сборщика мусора ни умных указателей, ну и защиты памяти нет. Все как в Си на голых "указателях" (или индексах - не важно).

А по поводу зарплат, если верить вот этому: http://habrahabr.ru/company/it_dominanta/blog/147866/ то разница средних зарплатах между С++ программером и С# программером в общем то и нет. А вот дисперсия да, у C++ больше
Вот поэтому надо ориентироваться не на среднюю, а на максимальную - каков потолок.

Кстати, в указанной тобой статье неверные данные по потолку зарплаты для С++ по Нижнему Новгороду. Там где я буду работать потолок зарплат выше, такой же высокий как для Java. То есть идти переучиваться в Java программиста только лишь из-за денег для меня смысла нет.
Дык за полтора то года зарплаты подросли.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: vlad от Октябрь 18, 2013, 03:22:35 pm
На этом моя борьба со сборщиком мусора закончена. Я меняю место работы. Работу я выполнял фактически сишную, а оплачивалась она по сишарповски. Исправляя этот дисбаланс, с понедельника перехожу на новое место работы, на котором буду программировать на C/C++.

Не забудь написать в тот эпичный тред про синтаксический оверхед на RSDN ;) Чтоб расставить все точки :)
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey_u от Октябрь 18, 2013, 03:32:27 pm
На этом моя борьба со сборщиком мусора закончена. Я меняю место работы. Работу я выполнял фактически сишную, а оплачивалась она по сишарповски. Исправляя этот дисбаланс, с понедельника перехожу на новое место работы, на котором буду программировать на C/C++.

Не забудь написать в тот эпичный тред про синтаксический оверхед на RSDN ;) Чтоб расставить все точки :)
Можно и на лурк сразу: http://lurkmore.to/Rsdn.ru#mws_5vpY5C4
Кто из нас еще может похвастатья что про него есть на лурке? :-)

На самом деле, профессионал (если он растет конечно) со временем вырастает из одного языка, и краткое "Программист на languageName" его уже не характеризует. Вот и все.
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: DddIzer от Октябрь 18, 2013, 03:43:25 pm

Можно и на лурк сразу: http://lurkmore.to/Rsdn.ru#mws_5vpY5C4
Кто из нас еще может похвастатья что про него есть на лурке? :-)

да Сергей крут...  :) ну положим, я в этом не сомневался уже после поста в блоге Чернова - где он определил его
"Си-шным рептилоидом-технофошистом."
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey_u от Октябрь 18, 2013, 04:21:43 pm

Можно и на лурк сразу: http://lurkmore.to/Rsdn.ru#mws_5vpY5C4
Кто из нас еще может похвастатья что про него есть на лурке? :-)

да Сергей крут...  :) ну положим, я в этом не сомневался уже после поста в блоге Чернова - где он определил его
"Си-шным рептилоидом-технофошистом."
Это что-ли вот это: http://avchernov.livejournal.com/312.html?thread=1592#t1592 ?
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: DddIzer от Октябрь 18, 2013, 04:38:37 pm

Можно и на лурк сразу: http://lurkmore.to/Rsdn.ru#mws_5vpY5C4
Кто из нас еще может похвастатья что про него есть на лурке? :-)

да Сергей крут...  :) ну положим, я в этом не сомневался уже после поста в блоге Чернова - где он определил его
"Си-шным рептилоидом-технофошистом."
Это что-ли вот это: http://avchernov.livejournal.com/312.html?thread=1592#t1592 ?
ага
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: valexey_u от Октябрь 18, 2013, 04:43:04 pm
Вообще, можно длинными осенними вечерами сидеть и перечитывать что мы писали в 2006 году скажем. Например на делфикиндом - бывает ОЧЕНЬ смешно :-)
Название: Re: Паузы в работе программы вызываемые GC
Отправлено: DddIzer от Октябрь 18, 2013, 04:52:31 pm
Вообще, можно длинными осенними вечерами сидеть и перечитывать что мы писали в 2006 году скажем. Например на делфикиндом - бывает ОЧЕНЬ смешно :-)
а я так и делаю (иногда)  :D