Здравствуйте, samius, Вы писали:
G>>>1) Никакого периодического процесса нет. Сборка мусора вызывается тогда когда памяти не хватает. ГВ>>По такой логике, любая программа на .Net должна для начала выедать всю доступную память, чего на практике обычно не происходит. S>Когда кончается не вся доступная память, а память в специальной арене для выделения (256Kb afair). Когда кончается эта арена — все на что есть ссылки выносится в первое поколение, указатель свободного места переносится на начало арены.
Вот мне и интересно как раз, каков будет консенсус вокруг "нехватки памяти".
G>>>4) Чтобы программа не тормозила не надо нарушать статистику, на основе которой построены алгоритмы GC, что с завидным упорством делают программисты C++ когда пишут на C#.
ГВ>>И в чём выражаются такие нарушения? S>фиксят указатели в unsafe. Наверное об этом...
Да нет, это слишком мрачно. Скорее всего, речь идёт о том, что долгоживущие объекты создают короткоживущие и размещают у себя ссылки на них, и поэтому приходится часто анализировать память, отнесённую к старшим поколениям. Длина анализируемого графаф увеличивается и т.п.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Здравствуйте, samius, Вы писали:
ГВ>>>Всё равно умудряется работать где-то на 5-7% медленнее C++-ного аналога (если хочешь, скину полные примеры). Хотя там JIT и инлайн делает, и лишние проверки выкидывает. S>>а если S>>
S>>i < arr.Length
S>>
S>>?
ГВ>Тогда скорость C# падает примерно в полтора раза.
Где-то читал что оптимизируется именно вариант с проверкой array.Length, и что не нужно создавать переменную под это...
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Здравствуйте, samius, Вы писали:
G>>>>1) Никакого периодического процесса нет. Сборка мусора вызывается тогда когда памяти не хватает. ГВ>>>По такой логике, любая программа на .Net должна для начала выедать всю доступную память, чего на практике обычно не происходит. S>>Когда кончается не вся доступная память, а память в специальной арене для выделения (256Kb afair). Когда кончается эта арена — все на что есть ссылки выносится в первое поколение, указатель свободного места переносится на начало арены.
ГВ>Вот мне и интересно как раз, каков будет консенсус вокруг "нехватки памяти".
Консенсус у кого c кем? Уверен, что gandjustas просто не уточнил, где именно не хватит памяти и какой именно памяти и спорить мы с ним по этому поводу не будем. Да и такой спор легко разрешился бы, делов-то дойти до шкафа с Рихтером и стряхнуть пыль с него.
ГВ>>>И в чём выражаются такие нарушения? S>>фиксят указатели в unsafe. Наверное об этом...
ГВ>Да нет, это слишком мрачно. Скорее всего, речь идёт о том, что долгоживущие объекты создают короткоживущие и размещают у себя ссылки на них, и поэтому приходится часто анализировать память, отнесённую к старшим поколениям. Длина анализируемого графаф увеличивается и т.п.
Вот этот сценарий — слишком мрачный. Думаю, что даже старички дотнетчики не заботятся о таких вещах.
Здравствуйте, samius, Вы писали:
ГВ>>>>Всё равно умудряется работать где-то на 5-7% медленнее C++-ного аналога (если хочешь, скину полные примеры). Хотя там JIT и инлайн делает, и лишние проверки выкидывает. S>>>а если S>>>
S>>>i < arr.Length
S>>>
S>>>?
ГВ>>Тогда скорость C# падает примерно в полтора раза. S>Где-то читал что оптимизируется именно вариант с проверкой array.Length, и что не нужно создавать переменную под это...
Да, так и есть. Вот такие варианты работают одинаково:
for (int j = 0, je = arr.Length; j < je; ++j)
for (int i = 0, ie = arr.Length; i < ie; ++i)
и
for (int j = 0; j < arr.Length; ++j)
for (int i = 0; i < arr.Length; ++i)
И они оба сильно отстают от:
for (int j = 0; j < ArrSize; ++j)
for (int i = 0; i < ArrSize; ++i)
Хотя массив создаётся в той же функции и казалось бы, можно определить константную длину.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, samius, Вы писали:
ГВ>>Вот мне и интересно как раз, каков будет консенсус вокруг "нехватки памяти". S>Консенсус у кого c кем? Уверен, что gandjustas просто не уточнил, где именно не хватит памяти и какой именно памяти и спорить мы с ним по этому поводу не будем. Да и такой спор легко разрешился бы, делов-то дойти до шкафа с Рихтером и стряхнуть пыль с него.
Я думаю, что оптимальный вариант — чтобы автор сам поправил ошибочные высказывания. Во избежание разночтений.
ГВ>>>>И в чём выражаются такие нарушения? S>>>фиксят указатели в unsafe. Наверное об этом... ГВ>>Да нет, это слишком мрачно. Скорее всего, речь идёт о том, что долгоживущие объекты создают короткоживущие и размещают у себя ссылки на них, и поэтому приходится часто анализировать память, отнесённую к старшим поколениям. Длина анализируемого графаф увеличивается и т.п. S>Вот этот сценарий — слишком мрачный. Думаю, что даже старички дотнетчики не заботятся о таких вещах.
Так именно такой сценарий и следует из слов gandjustas. И в принципе, он имеет право на существование.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Здравствуйте, samius, Вы писали:
S>>>>фиксят указатели в unsafe. Наверное об этом... ГВ>>>Да нет, это слишком мрачно. Скорее всего, речь идёт о том, что долгоживущие объекты создают короткоживущие и размещают у себя ссылки на них, и поэтому приходится часто анализировать память, отнесённую к старшим поколениям. Длина анализируемого графаф увеличивается и т.п. S>>Вот этот сценарий — слишком мрачный. Думаю, что даже старички дотнетчики не заботятся о таких вещах.
ГВ>Так именно такой сценарий и следует из слов gandjustas. И в принципе, он имеет право на существование.
Право имеет, но вряд ли такой сценарий в большей мере относится именно к программистам C++.
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Здравствуйте, gandjustas, Вы писали:
G>>Вообще-то в интернете информации полно о том как работает сборщик мусора в .NET и какие там оптимизации. Почитал бы уже давно, а не выдавал домыслы, услышанные от непонятно кого за чистую монету.
ГВ>Я знаю, что полно, но ты сам что именно посоветуешь? http://www.rsdn.ru/article/dotnet/GC.xml
это для начала
потом CLR via C# рихтера, только последней редакции
после этого http://msdn.microsoft.com/en-us/library/0xy59wtx(v=VS.110).aspx
А дальше можно просто гуглить.
G>>1) Никакого периодического процесса нет. Сборка мусора вызывается тогда когда памяти не хватает. ГВ>По такой логике, любая программа на .Net должна для начала выедать всю доступную память, чего на практике обычно не происходит.
Ты еще не формализовал понятие "не хватает".
G>>3) Но для сборки мусора в младших поколениях требуется анализ объектов из старших, но статистика показала что обычно не более 5% долгоживущих объектов ссылаются на короткоживущие и используется механизм защищенных страниц чтобы сборщи мусора узнавал о записи ссылок из младшего поколения в старшее. ГВ>OK. Про использование защищённых страниц я не знал (разве что краем уха слышал).
Я читал о таком механизме как о возможной оптимизации поколений (ссылку к сожалению не найду), но подобный механизм точно существует иначе .NET был бы не быстрее ruby.
Причем долгое время mono не имел generational GC и дико тормозил. Также generational gc отсутствует в xbox.
G>>4) Чтобы программа не тормозила не надо нарушать статистику, на основе которой построены алгоритмы GC, что с завидным упорством делают программисты C++ когда пишут на C#. ГВ>И в чём выражаются такие нарушения?
Например в создании долгоживущих объектов без необходимости. Вроде создания пула объектов для уменьшения количества выделений памяти (довольно частая оптимизация в unmanaged) в managed может приводить к отрицательным результатам.
Здравствуйте, gandjustas, Вы писали:
G>>>Вообще-то в интернете информации полно о том как работает сборщик мусора в .NET и какие там оптимизации. Почитал бы уже давно, а не выдавал домыслы, услышанные от непонятно кого за чистую монету.
ГВ>>Я знаю, что полно, но ты сам что именно посоветуешь? G>http://www.rsdn.ru/article/dotnet/GC.xml
А... Ну это-то я как раз читал. Ну, всё равно спасибо.
G>>>1) Никакого периодического процесса нет. Сборка мусора вызывается тогда когда памяти не хватает. ГВ>>По такой логике, любая программа на .Net должна для начала выедать всю доступную память, чего на практике обычно не происходит. G>Ты еще не формализовал понятие "не хватает".
По умолчанию мы считаем, что рассматривается вся доступная процессу память.
G>>>3) Но для сборки мусора в младших поколениях требуется анализ объектов из старших, но статистика показала что обычно не более 5% долгоживущих объектов ссылаются на короткоживущие и используется механизм защищенных страниц чтобы сборщи мусора узнавал о записи ссылок из младшего поколения в старшее. ГВ>>OK. Про использование защищённых страниц я не знал (разве что краем уха слышал). G>Я читал о таком механизме как о возможной оптимизации поколений (ссылку к сожалению не найду), но подобный механизм точно существует иначе .NET был бы не быстрее ruby.
OK, поищу тогда сам. Правда, пока что ничего не нашёл.
G>Причем долгое время mono не имел generational GC и дико тормозил. Также generational gc отсутствует в xbox.
G>>>4) Чтобы программа не тормозила не надо нарушать статистику, на основе которой построены алгоритмы GC, что с завидным упорством делают программисты C++ когда пишут на C#. ГВ>>И в чём выражаются такие нарушения? G>Например в создании долгоживущих объектов без необходимости. Вроде создания пула объектов для уменьшения количества выделений памяти (довольно частая оптимизация в unmanaged) в managed может приводить к отрицательным результатам.
А в чём тут отрицательное влияние выражается? В миграции ссылки на долгоживущий объект из памяти Gen2 в память Gen0?
Ну и потом, это не только из unmanaged, такой же подход используется в Java. Собственно, пулы хорошо решают задачу снижения издержек конструирования объектов, распределение памяти — только часть этой задачи.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
ГВ>А в чём тут отрицательное влияние выражается? В миграции ссылки на долгоживущий объект из памяти Gen2 в память Gen0?
основной ошибкой будет постоянное изменение ссылок из долгоживущих на короткоживущие.
это приведет к тому, что постоянно будет звенеть колокольчик, что произошло изменение страниц памяти с долгоживущими, и что их надо перепроверять при анализе для сборки мусора короткоживущих объектов.
соответственно, если объект просто используется из пула, то это даст ускорение, но если при этом в нем постоянно начинают меняться ссылки на другие объекты, хотя бы на строки, не говоря уже о других более сложные объектах, то может получится что такая оптимизация добавит больше работы gc, чем выиграет от повторного использования.
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Ну и потом, это не только из unmanaged, такой же подход используется в Java. Собственно, пулы хорошо решают задачу снижения издержек конструирования объектов, распределение памяти — только часть этой задачи.
В Java пулы используются для работы с объектами, создание которых действительно дорого. К примеру, потоками или соединениями с БД.
Основная проблема в пуловых объектах в том, что их мутация заметно дороже мутации объектов из нового поколения.
Здравствуйте, Cyberax, Вы писали:
ГВ>>Ну и потом, это не только из unmanaged, такой же подход используется в Java. Собственно, пулы хорошо решают задачу снижения издержек конструирования объектов, распределение памяти — только часть этой задачи. C>В Java пулы используются для работы с объектами, создание которых действительно дорого. К примеру, потоками или соединениями с БД.
C>Основная проблема в пуловых объектах в том, что их мутация заметно дороже мутации объектов из нового поколения.
В смысле?
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, DarkGray, Вы писали:
ГВ>>А в чём тут отрицательное влияние выражается? В миграции ссылки на долгоживущий объект из памяти Gen2 в память Gen0? DG>основной ошибкой будет постоянное изменение ссылок из долгоживущих на короткоживущие. DG>это приведет к тому, что постоянно будет звенеть колокольчик, что произошло изменение страниц памяти с долгоживущими, и что их надо перепроверять при анализе для сборки мусора короткоживущих объектов.
DG>соответственно, если объект просто используется из пула, то это даст ускорение, но если при этом в нем постоянно начинают меняться ссылки на другие объекты, хотя бы на строки, не говоря уже о других более сложные объектах, то может получится что такая оптимизация добавит больше работы gc, чем выиграет от повторного использования.
Ясно. Я как раз примерно об этом сценарии и подумал
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, DarkGray, Вы писали:
ГВ>>А в чём тут отрицательное влияние выражается? В миграции ссылки на долгоживущий объект из памяти Gen2 в память Gen0? DG>основной ошибкой будет постоянное изменение ссылок из долгоживущих на короткоживущие. DG>это приведет к тому, что постоянно будет звенеть колокольчик, что произошло изменение страниц памяти с долгоживущими, и что их надо перепроверять при анализе для сборки мусора короткоживущих объектов. DG>соответственно, если объект просто используется из пула, то это даст ускорение, но если при этом в нем постоянно начинают меняться ссылки на другие объекты, хотя бы на строки, не говоря уже о других более сложные объектах, то может получится что такая оптимизация добавит больше работы gc, чем выиграет от повторного использования.
Выглядит хорошим аргументом в пользу функционального стиля с иммутабельными объектами.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>"Традиционные" менеджеры памяти — это какие? Из MSC RTL? Так с ними сравнивать бессмысленно — там одна только блокировка/разблокировка хипа чего стоит.
Это любые, где требуются явные операции освобождения памяти.
ГВ>"Частота" свидетельствует о некотором периодическом процессе. "Долгоживущие объекты" — об анализе ссылок с сопутствующими холостыми проверками. ИМХО, всё это вместе как раз и есть та самая "регулярная проверка (анализ) состояния памяти". Я не прав?
Да, неправ. Рекомендую углубленный RTFM на тему.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
ГВ>>"Традиционные" менеджеры памяти — это какие? Из MSC RTL? Так с ними сравнивать бессмысленно — там одна только блокировка/разблокировка хипа чего стоит. S>Это любые, где требуются явные операции освобождения памяти.
Продвинутые аллокаторы используют локальные для потоков арены, там блокировка не нужна.
Здравствуйте, Cyberax, Вы писали: C>Продвинутые аллокаторы используют локальные для потоков арены, там блокировка не нужна.
Тем не менее, независимо от степени продвинутости аллокатора, при убийстве 100к объектов нужно 100к раз вызвать код возврата памяти в кучу.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
ГВ>>"Традиционные" менеджеры памяти — это какие? Из MSC RTL? Так с ними сравнивать бессмысленно — там одна только блокировка/разблокировка хипа чего стоит. S>Это любые, где требуются явные операции освобождения памяти.
Операции освобождения памяти требуются не менеджерами памяти, а программой, которая эти менеджеры использует. Можно грохнуть весь менеджер, ни разу не выполняя промежуточный delete.
ГВ>>"Частота" свидетельствует о некотором периодическом процессе. "Долгоживущие объекты" — об анализе ссылок с сопутствующими холостыми проверками. ИМХО, всё это вместе как раз и есть та самая "регулярная проверка (анализ) состояния памяти". Я не прав? S>Да, неправ. Рекомендую углубленный RTFM на тему.
Хорошо, пусть тогда это будет апериодический процесс, который вызывается по заполнении очередного сегмента (area). Скажи пожалуйста, как понимать выражение: "строится граф живых объектов"? AFAIK, чтобы построить такой граф, нужно пройти по ссылкам и как минимум, убедиться, что проверенные ссылки не нулевые. Или нет?
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Sinclair, Вы писали:
C>>Продвинутые аллокаторы используют локальные для потоков арены, там блокировка не нужна. S>Тем не менее, независимо от степени продвинутости аллокатора, при убийстве 100к объектов нужно 100к раз вызвать код возврата памяти в кучу.
Совершенно не обязательно.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>И они оба сильно отстают от:
ГВ>
ГВ>for (int j = 0; j < ArrSize; ++j)
ГВ> for (int i = 0; i < ArrSize; ++i)
ГВ>
В релизе? Не из-под студии?
Очень, очень странно. Опубликуй, пожалуйста, программу — студии под рукой нет.
И, да, выкинь нахрен DateTime. Пользуйся System.Threading.Timer. ГВ>Хотя массив создаётся в той же функции и казалось бы, можно определить константную длину.
К месту создания массива это отношения не имеет. Ресайза массивов в дотнете нет, поэтому можно закладываться на постоянство arr.Length в любом случае.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
ГВ>Операции освобождения памяти требуются не менеджерами памяти, а программой, которая эти менеджеры использует. Можно грохнуть весь менеджер, ни разу не выполняя промежуточный delete.
Скажем более общо: вызов операций удаления объектов определяется политикой управления памятью, которая, в свою очередь зависит от выбранной архитектуры, от задач приложения и кучи других соображений. Часть приложения может работать под одной политикой, часть под другой, часть — под третьей...
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!