Здравствуйте, remark, Вы писали:
R>А как они решили? Как в Java?
Боюсь наврать, так как давно изучал вопрос, но примерно было так.
В ЖЦ 1.х если находились заблокированные объекты, то сжатие за них не проводилось. Куча как бы застывала последнем запиненом объекте. Это приводило к тому, что куча со временем становилась фрагментированной. В итоге могла свободно кончиться память. В номом фрэймворке это как-то обошли. Как точно не помню. Проще поискать описание.
VD>>Ввывод — это не проблема GC в общем, а проблема конкретной реализации.
R>Это всё проблемы реализаций.
Ага.
R>Точнее так — это проблемы, с которыми можно сталкнуться в реальности, если используешь GC.
Не-ааа.
R> Возможно я немного неточно назвал тему...
Ты бы лучше создал бы тему по поводу недостатков обычных С-хипов. А то вот реализация что используется в Виндовс на редкость кривая и дико тормозит (особенно в многопточном окружении). Тогда бы мы поглядели что за выводы ты сделаешь. Ведь если идти твоим путем, то можно или Виндовс с дермом смешать или все С-хипы.
Если не понятно, то попробую пояснить на базе аналогии. Возьмем, к рпимеру, сотовые телефоны. То что у некоторых из них есть проблемы еще не значит, что все GSM-телефоны ущербны. Ну, мало ли там один из видов в одной из версий плохой прием имеет? Что с того? Вот то же самое с ЖЦ. Нельзя ставить ярмо на сам подход если в отдельных версях были некоторые проблемы.
VD>>Ни Ява, ни дотнет не содержат серьзных средств упрощающих многопоточную разработку. GC тут просто не причем.
R>GC тут косвенно при чём. Т.к. такие посты и заметки в блоках встречаются с некоторой регулярностью.
Тебе не кажется, что ты сам себе противоречишь?
VD>>Более того есть системы с GC которые как раз радикально упрощают разработку многопточных систем (Эрлэнг, Сингулярити и т.п.).
R>Они могли бы так же быть построены и на основе синхронного удаления объектов, используя подсчёт ссылок.
А это соврешенно не важно. Важно, что эти факты опровергают твои предположения о том, что ЖЦ мол как-то плохо влияет на многопоточне вычисления.
Подитоживая могу с уверенностью сказать, что твои выводы — это демонстрация некорректной логики. А это, в своею очередь, может быть или от плохого владения ею, или банальным не честным приемом дисскусси.
R>>>Какие мысли?
VD>>Мысль одна. Не следует обсуждать слухи. А уж если полез обсуждать, то разберись в проблематике.
R>Это не слухи. Это — факты. Факты про конкрутные реализации — не спорю.
VD>>GC не иделное решене. У него есть проблемы. Одна из главных проблем — это увеличение потребности в памяти. GC работает эффективно только при наличии запаса свободной памяти. Он как бы меняет лишнюю память на автоматическое упрваление ею.
VD>>Кроме того GC сам по себе не предоставляет средств управления другими ресурсами и выявления проблем с неосвобождением памяти (складыванием ее в кучу). Однако эти проблемы могут быть решены отладчиками, языками программирования и инструментальными средствами.
VD>>Ну, а описанные здесь "проблемы" не более чем громкие охания.
R>Да, это — действительно громкие охания... человека который провёл месяц в отладчике
R> R>
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Ты бы лучше создал бы тему по поводу недостатков обычных С-хипов. А то вот реализация что используется в Виндовс на редкость кривая и дико тормозит (особенно в многопточном окружении). Тогда бы мы поглядели что за выводы ты сделаешь. Ведь если идти твоим путем, то можно или Виндовс с дермом смешать или все С-хипы.
VD>Если не понятно, то попробую пояснить на базе аналогии. Возьмем, к рпимеру, сотовые телефоны. То что у некоторых из них есть проблемы еще не значит, что все GSM-телефоны ущербны. Ну, мало ли там один из видов в одной из версий плохой прием имеет? Что с того? Вот то же самое с ЖЦ. Нельзя ставить ярмо на сам подход если в отдельных версях были некоторые проблемы.
Влад, я ничего не говорил про GC в целом. Ты сам придумываешь какие-то аргументы за меня, а потом сам на них отвечаешь. Я имел в виду только то, что написал. Ни больше, и не меньше. Конкретные люди сталкнулись с конкретными проблемами. Ссылки я дал. Если там что-то некорректно написано, то обращайся к тем людям.
На всякий случай, про goto я тоже ничего не говорил
Здравствуйте, remark, Вы писали:
R>Третья проблема от огромных лозунгов, что все проблемы с управлением памятью и иже с ними временем жизни и владением — решены GC. GC решена только проблема управлением памятью. А время жизни и владение, как были одними из сложных проблем разработки ПО, так ими и остались. И эти моменты по прежнему надо продумывать и контролировать вручную.
R>Какие мысли?
Я бы добавил сюда еще одну проблему -- GC прощает ошибки программиста. Несколько раз уже с подобными вещами сталкивался, но детали забывались. А вот сегодня сделал у себя в C++ ошибку, которая проявилась бы в языке с GC по другому.
Суть вот в чем: есть два map-а, ключами в которых являются идентификаторы клиентов, а значениями -- ссылки на соответствующие этим клиентам объекты (в данном случае фильтры). В одном map-е хранятся фильтры, которые еще не прошли подтверждение, а во втором -- уже подтвержденые. И есть операция switch_to_delayed_filter, которая перемещает фильтр из одного map-а в другой, возвращая указатель на фильтр:
filter_t *
channel_filters_t::switch_to_delayed_filter(
const client_id_t & id )
{
// Ищем отложенный фильтр в map-е еще не подтвержденных.
filter_map_t::iterator it = m_delayed.find( id );
if( it != m_delayed.end() )
{
// Перемещаем из одного map-а в другой.
filter_t * result = it->second.get();
m_actual.insert( *it );
m_delayed.erase( it );
return result;
}
else// Ну нет такого фильра, пускай наверху разбираются.return 0;
}
Ошибка состояла в том, что при некоторых стечениях обстоятельств для одного и того же id фильтры оказывались одновременно в m_actual и m_delay. И операция m_actual.insert() в этом случае ничего не делала. Соответственно, объект, на который указывает result уничтожался во время m_delayed.erase(). И switch_to_delayed_filter возвращает повисший указатель. Что приводит к краху приложения.
Собственно, это явилось следствием другой более важной ошибки: не должно быть одинакового id в m_actual и m_delayed в одно и то же время. Но, в конце-концов приложение просто свалилось и это заставило меня найти все причины.
А в случае с GC объект result содержал бы валидную ссылку. И оказалось бы, что switch_to_delayed_filter возвращает совсем не тот фильтр, который находится в m_actual. И ничего бы не падало. Просто работало бы не так как нужно. И еще не понятно, когда бы все всплыло, ведь в тестах у меня все клиенты использовали одинаковые фильтры
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>А в случае с GC объект result содержал бы валидную ссылку. И оказалось бы, что switch_to_delayed_filter возвращает совсем не тот фильтр, который находится в m_actual. И ничего бы не падало. Просто работало бы не так как нужно. И еще не понятно, когда бы все всплыло, ведь в тестах у меня все клиенты использовали одинаковые фильтры
Прочитай в MSDN про Dictionary.System.Collections.IDictionary.Add раздел Exceptions...
ЗЫ А вобще логика офигенная: ГЦ плохо по тому что у меня руки кривые.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
[]
E>Суть вот в чем: есть два map-а, ключами в которых являются идентификаторы клиентов, а значениями -- ссылки на соответствующие этим клиентам объекты (в данном случае фильтры). В одном map-е хранятся фильтры, которые еще не прошли подтверждение, а во втором -- уже подтвержденые. И есть операция switch_to_delayed_filter, которая перемещает фильтр из одного map-а в другой, возвращая указатель на фильтр: E>
E>filter_t *
E>channel_filters_t::switch_to_delayed_filter(
E> const client_id_t & id )
E> {
E> // Ищем отложенный фильтр в map-е еще не подтвержденных.
E> filter_map_t::iterator it = m_delayed.find( id );
E> if( it != m_delayed.end() )
E> {
E> // Перемещаем из одного map-а в другой.
E> filter_t * result = it->second.get();
E> m_actual.insert( *it );
E> m_delayed.erase( it );
E> return result;
E> }
E> else
E> // Ну нет такого фильра, пускай наверху разбираются.
E> return 0;
E> }
E>
[]
как я понял, фильтр в delayed != фильтру в actual? Прости, но кто так делает (см. выд.)? Ты ССЗБ
E>> // Перемещаем из одного map-а в другой.
E>> filter_t * result = it->second.get();
E>>
КЛ>как я понял, фильтр в delayed != фильтру в actual? Прости, но кто так делает (см. выд.)? Ты ССЗБ
А что такого? В map-е значением лежит shared_ptr, его метод get() возвращает голый указатель, который мне нужен был для возвращаемого значения. При условии, что это shared_ptr не разрушается при переносе из map-а в map, криминала я не вижу.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, WolfHound, Вы писали:
WH>ЗЫ А вобще логика офигенная: ГЦ плохо по тому что у меня руки кривые.
Нет, логика такая — GC плох потому, что он жрет мозг. И самая главная подлость GC — он делает это так незаметно, что жертва GC, сама того не сознавая, начинает молиться на него, воздавать хвалы и выполнять ритуальные жертвоприношения.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, McSeem2, Вы писали:
MS>Нет, логика такая — GC плох потому, что он жрет мозг. И самая главная подлость GC — он делает это так незаметно, что жертва GC, сама того не сознавая, начинает молиться на него, воздавать хвалы и выполнять ритуальные жертвоприношения.
Мы где? В семенарии или на техническом форуме?
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, McSeem2, Вы писали:
MS>GC плох потому, что он жрет мозг. И самая главная подлость GC — он делает это так незаметно, что жертва GC, сама того не сознавая, начинает молиться на него, воздавать хвалы и выполнять ритуальные жертвоприношения.
Какая страшная история. А компилятор тоже жрет мозг?
... << RSDN@Home 1.2.0 alpha rev. 746>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
[]
E>А что такого? В map-е значением лежит shared_ptr, его метод get() возвращает голый указатель, который мне нужен был для возвращаемого значения. При условии, что это shared_ptr не разрушается при переносе из map-а в map, криминала я не вижу.
Вот потому и получил эту проблему, что не видишь. Просто небезопасно это. Я так очень редко делаю.
Обычно так:
filter_tptr filter = filters[ id ];
или
filter_tptr const& filter = filters[ id ];
Здравствуйте, Константин Л., Вы писали:
E>>А что такого? В map-е значением лежит shared_ptr, его метод get() возвращает голый указатель, который мне нужен был для возвращаемого значения. При условии, что это shared_ptr не разрушается при переносе из map-а в map, криминала я не вижу.
КЛ>Вот потому и получил эту проблему, что не видишь. Просто небезопасно это. Я так очень редко делаю. КЛ>Обычно так:
КЛ>
КЛ>filter_tptr filter = filters[ id ];
КЛ>
На неконстантном map-е оператор[] для несуществующего ключа может привести к интересным глюкам -- вставке пустого элемента в map. А если воспользоваться map::find, то уже есть iterator, из которого можно брать все, что нужно.
КЛ>Ну а уж голый поинтер возвращать — нерулез.
Снаружи switch_to_delayed_channel мне нужен был именно указатель, т.к. то, что внутри хранилища фильтров используются shared_ptr -- это детали реализации, которые клиентов хранилища интересовать не должны.
К тому же возвращение shared_ptr в данном случае привело бы к сокрытию проблемы, как и в случае GC.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
[]
E>На неконстантном map-е оператор[] для несуществующего ключа может привести к интересным глюкам -- вставке пустого элемента в map. А если воспользоваться map::find, то уже есть iterator, из которого можно брать все, что нужно.
совершенно верно, это был псевдокод
КЛ>>Ну а уж голый поинтер возвращать — нерулез.
[]
E>К тому же возвращение shared_ptr в данном случае привело бы к сокрытию проблемы, как и в случае GC.
Ну к сокрытию проблемы может привести все, что угодно. Так что, по моему мнению, гц тут не при чем.
Неплохо бы проверять результат map::insert. Да и вообще — обычный bl баг
Здравствуйте, Константин Л., Вы писали:
КЛ>Ну к сокрытию проблемы может привести все, что угодно. Так что, по моему мнению, гц тут не при чем.
КЛ>Неплохо бы проверять результат map::insert.
Может быть, но я так и не научился писать код вида:
if( !m_actual.insert( *it ) )
abort(); /* больше уже все равно ничего не сделать */
КЛ>Да и вообще — обычный bl баг
Мой поинт был в том, что если из-за bl бага в C/C++ оказывается бесхозный указатель, то это приводит к краху программы. А в случае с GC бесхозная ссылка оставить программу работать.
Т.е. GC прощает ошибки там, где явное управление памятью со всей силы бьет по рукам.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Может быть, но я так и не научился писать код вида: E>
E>if( !m_actual.insert( *it ) )
E> abort(); /* больше уже все равно ничего не сделать */
E>
template<typename container_t>
void ensure_insert(container_t& c, typename container_t::const_reference v)
{
if (!c.insert(v).second)
{
assert(false);
throw std::logic_error("element doubling");
// or just abort()
}
}
ensure_insert(m, *it);
Во-первых, вместо просто abort(), желательно вначале сделать assert(false), т.к. ошибка логическая.
Во-вторых, стандартной библиотеке, действительно, не хватает многих удобных функций, типа таких:
R>>>Я не помню, что бы слышал какие либо нарекания именно в адрес самих malloc/free. GZ>>Дефрагментация.
видмо, всё же фрагментация
E>Если чесно, то никогда с этой проблемой на практике не сталкивался.
а я вот сталкиваюсь каждвый жень. бразуер запущен постоянно, в нём открываешь одни окна, закрываешь другие. в резудльтате обзийц обхём открытых данных остаётся примерно постоянным, а память течёт
Здравствуйте, remark, Вы писали:
R>Влад, я ничего не говорил про GC в целом. Ты сам придумываешь какие-то аргументы за меня, а потом сам на них отвечаешь. Я имел в виду только то, что написал. Ни больше, и не меньше. Конкретные люди сталкнулись с конкретными проблемами. Ссылки я дал. Если там что-то некорректно написано, то обращайся к тем людям.
ОК. Тогда зачем вся эта тема? Ну, какова ее цель? Ведь конкретные люди сталкивались с конкретными проблемами и при работе с кучей С/С++. Почему ты не посвятил свою тему этому?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
R>>Влад, я ничего не говорил про GC в целом. Ты сам придумываешь какие-то аргументы за меня, а потом сам на них отвечаешь. Я имел в виду только то, что написал. Ни больше, и не меньше. Конкретные люди сталкнулись с конкретными проблемами. Ссылки я дал. Если там что-то некорректно написано, то обращайся к тем людям.
VD>ОК. Тогда зачем вся эта тема? Ну, какова ее цель? Ведь конкретные люди сталкивались с конкретными проблемами и при работе с кучей С/С++. Почему ты не посвятил свою тему этому?
А почему я не посвятил свою тему арбузам? Многим бы было интересно.
А почему ты не посвящаешь свои темы организации кэшей современных процессоров? Мне было бы интересно!
Или тут можно постить только по квотам от тебя?
Здравствуйте, remark, Вы писали:
VD>>ОК. Тогда зачем вся эта тема? Ну, какова ее цель? Ведь конкретные люди сталкивались с конкретными проблемами и при работе с кучей С/С++. Почему ты не посвятил свою тему этому?
R>А почему я не посвятил свою тему арбузам? Многим бы было интересно. R>А почему ты не посвящаешь свои темы организации кэшей современных процессоров? Мне было бы интересно! R>Или тут можно постить только по квотам от тебя?
Так ответ на мой вопрос будет? Или дальше продолжишь заниматься демагогией?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.