Re[14]: Конец нересурсов
От: vdimas Россия  
Дата: 21.11.11 08:16
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

И да, многое поменялось. Например, boost уже не тот, чтоб был в 2002-м (накануне принятия стандарта C++03), можно смело пользоваться.
Re[23]: Конец нересурсов
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 21.11.11 08:24
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, gandjustas, Вы писали:


_>>>Кстати, с ocaml всё не совсем так.

G>>Что ты имеешь ввиду? Что он не использует данные о типах? Тогда как он мусор собирает?

FR>Использует битовый тег и унифицированные блоки памяти, для того чтобы отличать то что нужно собирать.


То есть метаинфорамция таки есть. Но за счет большей строгости языка её нужно меньше.
Re[15]: Конец нересурсов
От: mrTwister Россия  
Дата: 21.11.11 08:28
Оценка: :))) :)
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, Sinclair, Вы писали:


V>Ну ты привел проекты очень давние, во-первых, во-вторых, опен-сорс по большей части студенты (или вчерашние студенты) пишут. Опен-сорс, это такая площадка для набития руки.

V>Я тебе целиком в личку свежие коммерческие проекты на С++ могу закинуть, на предмет поиска голых указателей вне private кода.

V>И да, многое поменялось. Например, boost уже не тот, чтоб был в 2002-м (накануне принятия стандарта C++03), можно смело пользоваться.


Какие умные указатели? Это же удар по производительности и "снижение энергоэффективности" (с) ГВ!
Куча тактов процессора и байтов памяти зазря тратятся.
Настоящий С++'ник на такое варварство ни за что не согласится. А если видите, что кто-то увлекся умными указателями, то все, на нем можно ставить крест. Ибо стал на скользкую дорожку и скоро скатится до .NET'a
лэт ми спик фром май харт
Re[24]: Конец нересурсов
От: FR  
Дата: 21.11.11 08:41
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>То есть метаинфорамция таки есть. Но за счет большей строгости языка её нужно меньше.


Ну в таких и даже больших количествах метаинформация и в С++ есть, а в D или скажем дельфийском
Object Pascal ее на порядок больше, что не делает их управляемыми.
Re[19]: Конец нересурсов
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 21.11.11 08:41
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>ЧСХ, без моего желания C++ тоже не начнёт вольным образом реинтерпретировать память. А ошибки, связанные с нарушениями инвариантов могут быть абсолютно в любом коде — managed, unmanaged, свой, чужой — без разницы.


Неверно. Ты напишешь функцию, которая к полю объекта обращается. А кто-то до вызова твоей функции выполнит delete объекта, а потом на его месте новый создаст. Причина ошибки в таких случаях может находиться очень далеко от места возникновения, в отличии от managed, который еще и staktrace покажет и можно будет спокойно по дереву вызовов пройтись и узнать кто неверные данные передал.



V>>>Откуда же такое внимание к ошибкам именно в нейтиве?

T>>Потому что поиск и исправление бага в нейтив коде стоит на порядок дороже поиска и исправления бага в управляемом коде. Тому есть несколько причин:

ГВ>Некоторое время назад (не прошло и эм-м-м... примерно тридцати месяцев с тех пор) мне довелось лечить одну ошибку в комплексе managed+unmanaged. Классика жанра: AVE, чёрт-те что на выходе из unmanaged и далее по списку. Я когда увидел — ну всё, думаю, вот оно, тайное колдунство unmanaged. Добегался по форумам за "дотнетчиками", задавака хренов — вот сам теперь по носу своему задранному и получил. А ведь говорили, предупреждали хором: тайные ошибки — это вотчина unmanaged, и делают их не только вчерашние студенты. Короче, сел на измену, долго и тщательно копал — ничего. Ну, думаю, страус твои перья — и правда, пора C++ выкидывать, раз даже я в нём разобраться не могу. Короче, дня два или три я просидел на этой, довольно крутой измене, но как я ни искал ошибку в unmanaged — ни-фи-га. Поскольку код был мой, осознание этого факта добавляло мне острых ощущений.


ГВ>Потом думаю: не, что-то тут не то. Сильно не то. А, там ещё был нюанс: unmanaged-код был спроектирован исключительно под single-thread, а защиты от параллельного доступа предусмотрено не было (ради оптимизации, конечно). Естественно, были подозрения, что дело в параллельном доступе, но как-то... В общем, просматривали мы тот managed-код, но ничего подозрительного не обнаружили. Да и в остальном он работал без особых нареканий, так что, подозрения казались безосновательными.


ГВ>Короче, в качестве последней надежды я поставил блокировку параллельного обращения на входе в unmanaged. Так, на всякий случай, чем чёрт не шутит?


ГВ>Продолжать рассказывать или уже ясно? Да, через пару минут я получил диагностику параллельного обращения. В общем, в этом корректно работающем managed-коде была классическая concurrency-ошибка параллельного вызова того, что так вызывать в принципе нельзя, да никогда и не планировалось. Особую пикантность всей ситуации придавало то, что в остальном код работал, скажем так, вполне нормально — ну, может быть, кое-какие странности были, но мы их списывали на трудности "реальных условий". Короче: тишь, гладь, AVE, злобный C++, ухмылка Страуструпа на фоне клубов серного дыма.


Аааааа, я валаюсь. То есть код на C++ не был спроектировам под concurrency при этом сам проверок никаких не делал и ты говорищь что это ошибка managed кода?
Ну тогда любая ошибка — ошибка managed ибо не те параметры в unmanaged передаются.
ГВ>Дальше всё пошло своим чередом: разобрались, поправили, вытерли пот со лба, облегчённо вздохнули. Однако я вынес из этого несколько очень полезных для себя уроков.

ГВ>1) Нельзя вестись на поводу у дурацких стереотипов, что в AVE всегда виноват unmanaged.

Ок, докажи обратное. Когда чисто managed код вызывает AVE.

ГВ>2) Managed-код превосходно замаскировал ошибки concurrency и маскировал бы их дальше, если бы именно unmanaged не разорался во всю глотку о том, что что-то пошло не так.

То есть managed код работал, а unmanaged таки падал? Ведь именно unmanaged не был спроектирован под cuncurrency.

ГВ>3) Если бы не unmanaged, поиски тщательно замаскированной ошибки стали бы для нас чем-то вроде специальной олимпиады: главное не победа, главное — держаться подальше;

Без unmanaged скорее всего косяк был бы найден раньше ибо в managed из unmanaged не попадет сведений о threading model вызываемого кода.

ГВ>В общем, факт остаётся фактом: если бы на хвосте managed не висел сквалыга-unmanaged, ошибку пришлось бы искать гораздо дольше, а то и вообще она проплыла бы мимо. Ведь сложность поиска бага на самом деле зависит не от "управляемости" кода, а от того, какой это баг. В managed-коде причины багов ничуть не легче раскапывать, чем в unmanaged, а подчас и тяжелее из-за его всепроникающей "корректности", которая позволяет ему проглатывать то, что валит unmanaged.

Я так понимаю что ошибки бы и не было если бы не unmanaged.
Re[25]: Конец нересурсов
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 21.11.11 08:49
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, gandjustas, Вы писали:


G>>То есть метаинфорамция таки есть. Но за счет большей строгости языка её нужно меньше.


FR>Ну в таких и даже больших количествах метаинформация и в С++ есть, а в D или скажем дельфийском

FR>Object Pascal ее на порядок больше, что не делает их управляемыми.

В pascal или delphi она никак не используется средой выполнения, поэтому managed они не становятся.
Re[11]: Конец нересурсов
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 21.11.11 09:01
Оценка:
Здравствуйте, c-smile, Вы писали:

G>>Evernote был написан толпой C++ программистов. Думаю одна из причин низкой производительности была именно в этом.


CS>Тут одно утверждение и одно предположение. Оба неверные. Толпы в EverNote никогда не было это точно.

"Двое — уже толпа". Слово "толпа" сильно образное. Причем если программистов было мало, то переписывание с C++ на .NET с большей вероятностью приведет к неудовлетворительноу результату.

CS>По поводу WPF и .NET UI вообще.


CS>UI использующий DOM (например WPF и web, browser based UI) это как правило большой набор достаточно мелких объектов которые живут в GC heap.

CS>При этом в WPF DOM существенно низкоуровневый. Там где в browser используется один объект DOM элемент и его субобъект style (в терминах GCable сущностей) в WPF появляется примерно десяток отдельных GCable things. Т.е. WPF своей моделью создает существенную нагрузку на GC.
CS>Особенно на этапе запуска / инициализации всего хозяйства. Для Evernote как приложения запуск как раз и есть один из частых моментов. Приложение предполагается быть легковесным в этом смысле: открыл — сделал заметку — закрыл. Нужно вспомнить что-то: открыл — посмотрел — закрыл.
CS>Т.е. WPF для такого типа приложений очень неудачный инструмент. Для вещей типа Paint.Net он подходит наверное лучше.

Для быстрого старта надо не выгружать приложение из памяти после первого запуска. Так например metro работает в windows 8.
Долгий запуск — действительно проблема для WPF, но её можно скрыть как минимум.

Кстати в винде даже нативные notes первый раз стартуют заметное время. Но после добавления закладок они стартуют с виндой и не выгружаются.
Аналогичный инструмент MS Office OneNote тоже небысстро стартует, но у него в трее висит иконка (а соотвественно работает процесс), который позволяет быстро создать заметку.
При этом будучи запущенным постоянно тоже неплохо работает.

CS>Ну и потом HTML DOM скажем оперирует более высокоуровневыми конструкциями чем набор примитивов WPF. Т.е. в HTML DOM больше доля native code и memory management не связанной с GC. HTML DOM потенциально более GPU friendly. В WPF же надо конкретно знать детали имплементации чтобы достичь приемлемого результата.

Да, wpf сложен, особенно для нетривиальных интерфейсов.
Re[20]: Конец нересурсов
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 21.11.11 09:15
Оценка: +1
Здравствуйте, mrTwister, Вы писали:

ГВ>>ЧСХ, без моего желания C++ тоже не начнёт вольным образом реинтерпретировать память. [...]

T>К сожалению, в сложных проектах, которые делаются более чем одной командой, еще как начинает.

Сам начинает? А он как это делает, по вторникам, или по пятницам?

T>Тоже мне удивил. Именно про твою историю я писал следующее:

T>

Ну ты сравнил попу с пальцем! Без твоего, как автора кода, желания никто не заставит тебя сохранить null, в отличии от C++, где как бы ты аккуратно не писал, любой сторонний компонент может испортить твою память. Даже если этот компонент сам-по себе написан аккуратно, используя современные техники С++. Например, из-за ошибок связанных с concurrentcy, либо из-за того, что этот компонент как-то не так использовали.


Правильно. И я как раз не возражаю против этого.

ГВ>>2) Managed-код превосходно замаскировал ошибки concurrency и маскировал бы их дальше, если бы именно unmanaged не разорался во всю глотку о том, что что-то пошло не так.

T>Каким образом он их замаскировал?

Да вот тем самым, когда вместо двух объектов оказывался один.

ГВ>>4) Ошибки в unmanaged-коде, действительно, неимоверно сложно искать... В особенности, когда их там нет и ты точно знаешь, что их там нет.

T>То есть другими словами, работать с unmanaged кодом очень сложно, так как если ты при работе совершишь ошибку (начнешь использовать в несколько потоков, вместо одного), то вылавить эту ошибку будет очень трудно, так как получишь произвольную стрельбу по памяти. Причем в каком коде (managed или unmanaged) ты совершишь ошибку неправильного использования unmanaged кода, в любом случае тубу будет очень весело.

Нет, именно теми словами, которыми написано: трудно искать чёрную кошку в тёмной комнате, когда её нет.

ГВ>>В общем, факт остаётся фактом: если бы на хвосте managed не висел сквалыга-unmanaged, ошибку пришлось бы искать гораздо дольше, а то и вообще она проплыла бы мимо.

T>С чего ты это взял? В твоем случае тебе повезло, что оно просто упало. А ведь могла вместо этого отвалиться совершенно левая функциональность, которая к данному коду вообще не имеет никакого отношения. А так радуйся, что пронесло в этот раз.

Некоторые детали мне пришлось опустить. А потом проезд по памяти с разносом всего, включая GC-хип бы бы благом, поскольку заставил бы обратить внимание на эту ошибку намного раньше. К слову сказать, AVE в какой-то момент был у меня единственным методом диагностики. AVE и непосредственно предшествующее ему состояние памяти.

ГВ>>Ведь сложность поиска бага на самом деле зависит не от "управляемости" кода, а от того, какой это баг.

T>Совершенно верно. При этом самые сложные для поиска баги — это баги, специфичные для С++, а именно проход по памяти, некорректная её интерпретация и пр.

Мантра. Даже обсуждать не хочу. Как раз из-за того, что не раз такие ошибки и делал, и лечил (не только у себя).

ГВ>>В managed-коде причины багов ничуть не легче раскапывать, чем в unmanaged, а подчас и тяжелее из-за его всепроникающей "корректности", которая позволяет ему проглатывать то, что валит unmanaged.

T>Легче из-а отсутствия наиболее противных багов и наличия нормальных исключений с callstack'ами и сообщениями.

Вот странное дело. Сколько пишу на этом кошмарном C++, а самые противные баги — из-за бестолковой спецификации. ЧЯДНТ?

ГВ>>У меня даже закралась крамольная мысль, [...]

T>Контракты тебя спасут. В отличии от С++, в котором даже контракты не помогут, так как ничего не стоит эти контракты кому угодно разрушить без твоего ведома.

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

T>>>1) Ошибки в управляемом коде более локализованы. Одному компоненту труднее нарушить работу другого


ГВ>>Заблуждение. С неимоверной лёгкостью при concurrency-ошибках можно получить совместное владение одним объектом вместо двух, никто и слова худого не скажет. Один объект будет при этом ухлопан, а второй окажется в обоих потоках. И никакого шума, поскольку: а) для обновления ссылок синхронизация не требуется, б) клиент не управляет удалением объекта и там, где unmanaged непременно даст диагностику двойного удаления, managed — стоически промолчит.


T>Локализованы — это значит, что у тебя не сломается не связанная с этими объектами функциональность. [...] В частности, благодаря наличию метаданных твоя ошибка ищется очень просто: в windbg ты можешь сдампить все объекты интересующиего тебя типа, посмотреть их количество, и проверить все ссылки, кто на что ссылается. В частности, как только тестировщик видит, что приложение падает (из-за нарушения контракта), либо работает некорректно, то он делает дамп, отдает его тебе, ты видишь, что объектов два вместо одного, кричишь WTF, смотришь на код, который их создает и видишь, что этот код ломается в случае параллельного доступа. Все просто и скучно, никакого веселья и гадания на кофейной гуще, как в С++.


Хм. Я, вроде, понятно высказался: один объект вместо двух. Если они используются как read-only, ошибок попросту не будет. Вернее, они будут проявляться очень косвенно. Какая именно функциональность поломается — трудно предсказать в любом случае.

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

ГВ>>Потом, например, параллельный доступ к тому же Dictionary может привести к весьма загадочным ситуациям (по этому поводу тут Klatu как-то возмущался). А поиски причин могут быть очень нетривиальными, в особенности, если этот Dictionary уедет ещё куда-то.

T>Эти загадочные сидуации будут касаться только кода, связанного с этим Dictionary. Уши при этом у тебя не отвалятся. А в С++ возможно все.

В целом верно, но это, в сущности, не так уж плохо, поскольку заставляет внимательнее относиться к программированию.

T>>>2) Наличие коллстеков у всех исключений.

ГВ>>Не надо преувеличивать: сам по себе коллстек показывает лишь на место возникновения сбоя, но ничего не говорит о той цепи причин, которые привели к его возникновению (кроме непосредственной). Об этом было говорено-переговорено лет семь-восемь назад.
T>В 90% случаев этого достаточно. В С++ нет даже этого. Ты просто знаешь, что что-то где-то сломалось. Что и где — неизвестно. Если не удалось поймать дамп в момент падения, то начинается веселье.

Чушь. В C++, в случае выбрасывания исключения я знаю о происходящем ровно столько же, сколько и в C#: что в точке файл... строка... вылетело исключение. Информация о стеке... Ну как, может быть полезна с некоторой вероятностью, но не более того. А о действительных причинах в этот момент я всё равно могу только догадываться.

T>>>3) Типобезопасность — отсутствие возможности неправильно интерпретировать память или интерфейсы.

ГВ>>Ещё раз повторяю для дотнетчиков: ошибки типобезопасности вычисляются и лечатся на раз. [...]
T>Ситуация из недавней практики: поскольку проект очень большой, то его части собираются в разное время (чтобы оптимизировать время сборки). Однажды произошла такая ситуация, когда версия хедеров перестала соответствовать бинарям (забыли пересобрать). И продукт при этом работал практически всегда, но иногда в очень редких кейзах начинал течь. Сил угрохали на поиск в коде бага море. А в .NET такое невозможно в принципе.

И о чём это говорит? Да ни о чём. Собирать модули надо с соблюдением процедуры, больше ничего.

ГВ>>Так что, всё, что ты перечислил — оно, конечно, правильно, но практика — вещь такая...

T>Все, что я перечислял касается именно практики по интеграции большого количества unmanaged кода, написанного разными командами с большим количеством managed кода.

Как видишь, у каждого свои выводы из практики.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[26]: Конец нересурсов
От: FR  
Дата: 21.11.11 09:15
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>В pascal или delphi она никак не используется средой выполнения, поэтому managed они не становятся.


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

http://docwiki.embarcadero.com/RADStudio/en/Run-Time_Operations_on_Types
http://docwiki.embarcadero.com/RADStudio/en/Extracting_Attributes_at_Run_Time
Re[20]: Конец нересурсов
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 21.11.11 09:29
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Геннадий Васильев, Вы писали:


ГВ>>ЧСХ, без моего желания C++ тоже не начнёт вольным образом реинтерпретировать память. А ошибки, связанные с нарушениями инвариантов могут быть абсолютно в любом коде — managed, unmanaged, свой, чужой — без разницы.


G>Неверно. Ты напишешь функцию, которая к полю объекта обращается. А кто-то до вызова твоей функции выполнит delete объекта, а потом на его месте новый создаст. Причина ошибки в таких случаях может находиться очень далеко от места возникновения, в отличии от managed, который еще и staktrace покажет и можно будет спокойно по дереву вызовов пройтись и узнать кто неверные данные передал.


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

G>Аааааа, я валаюсь. То есть код на C++ не был спроектировам под concurrency при этом сам проверок никаких не делал и ты говорищь что это ошибка managed кода?


Именно.

G>Ну тогда любая ошибка — ошибка managed ибо не те параметры в unmanaged передаются.


Нет, не любая.

ГВ>>Дальше всё пошло своим чередом: разобрались, поправили, вытерли пот со лба, облегчённо вздохнули. Однако я вынес из этого несколько очень полезных для себя уроков.


ГВ>>1) Нельзя вестись на поводу у дурацких стереотипов, что в AVE всегда виноват unmanaged.

G>Ок, докажи обратное. Когда чисто managed код вызывает AVE.

Что — обратное?

ГВ>>2) Managed-код превосходно замаскировал ошибки concurrency и маскировал бы их дальше, если бы именно unmanaged не разорался во всю глотку о том, что что-то пошло не так.

G>То есть managed код работал, а unmanaged таки падал? Ведь именно unmanaged не был спроектирован под cuncurrency.

Умничка. Именно дотнетный код — работал. Ну, по вашему же, если эксцепшенов нет, значит код — работает! Возьми с полки пирожок. Ты, кстати, не у конкурентов, часом работаешь? Надо посоветовать, чтобы тебе зарплату подняли. Скажи, эдипов папа посоветовал.

ГВ>>3) Если бы не unmanaged, поиски тщательно замаскированной ошибки стали бы для нас чем-то вроде специальной олимпиады: главное не победа, главное — держаться подальше;

G>Без unmanaged скорее всего косяк был бы найден раньше ибо в managed из unmanaged не попадет сведений о threading model вызываемого кода.

Без unmanaged ошибка не была бы найдена вообще. Но она от этого никуда бы не делась.

ГВ>>В общем, факт остаётся фактом: если бы на хвосте managed не висел сквалыга-unmanaged, ошибку пришлось бы искать гораздо дольше, а то и вообще она проплыла бы мимо. Ведь сложность поиска бага на самом деле зависит не от "управляемости" кода, а от того, какой это баг. В managed-коде причины багов ничуть не легче раскапывать, чем в unmanaged, а подчас и тяжелее из-за его всепроникающей "корректности", которая позволяет ему проглатывать то, что валит unmanaged.

G>Я так понимаю что ошибки бы и не было если бы не unmanaged.

Ты не понял ничего.©
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[16]: Конец нересурсов
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 21.11.11 09:33
Оценка: +2
Здравствуйте, mrTwister, Вы писали:

V>>И да, многое поменялось. Например, boost уже не тот, чтоб был в 2002-м (накануне принятия стандарта C++03), можно смело пользоваться.


T>Какие умные указатели? Это же удар по производительности и "снижение энергоэффективности" (с) ГВ!

T>Куча тактов процессора и байтов памяти зазря тратятся.
T>Настоящий С++'ник на такое варварство ни за что не согласится. А если видите, что кто-то увлекся умными указателями, то все, на нем можно ставить крест. Ибо стал на скользкую дорожку и скоро скатится до .NET'a

Вот это и есть проблема апологетов дотнета: если их послушать, то можно сделать предположение, что они абсолютно не верят в людей. Ну то есть люди не совершенны, это понятно, но в устах "дотнетчиков" это несовершенство приобретает какие-то гротескные черты, прямо как у Босха.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[11]: Конец нересурсов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.11.11 09:46
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>UI использующий DOM (например WPF и web, browser based UI) это как правило большой набор достаточно мелких объектов которые живут в GC heap.

CS>При этом в WPF DOM существенно низкоуровневый. Там где в browser используется один объект DOM элемент и его субобъект style (в терминах GCable сущностей) в WPF появляется примерно десяток отдельных GCable things. Т.е. WPF своей моделью создает существенную нагрузку на GC.

Тут нужно понимать масштабы. Заметная нагрузка на GC это сотни тысяч — миллионы объектов. В типичной WPF форме столько даже близко нет.

CS>Особенно на этапе запуска / инициализации всего хозяйства. Для Evernote как приложения запуск как раз и есть один из частых моментов. Приложение предполагается быть легковесным в этом смысле: открыл — сделал заметку — закрыл. Нужно вспомнить что-то: открыл — посмотрел — закрыл.


Вот уж на инициализацию вряд ли влияет скорость сборки мусора.
Основные причины тормозов весьма традиционны для МС — медленный рендерер.

CS>В WPF же надо конкретно знать детали имплементации чтобы достичь приемлемого результата.


WPF изначально проектировался GPU friendly, в отличие от.
... << RSDN@Home 1.2.0 alpha 5 rev. 1537 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[21]: Конец нересурсов
От: mrTwister Россия  
Дата: 21.11.11 09:49
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:


Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>Сам начинает? А он как это делает, по вторникам, или по пятницам?

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

ГВ>Да вот тем самым, когда вместо двух объектов оказывался один.

И что? При чем тут управляемость кода?

ГВ>Нет, именно теми словами, которыми написано: трудно искать чёрную кошку в тёмной комнате, когда её нет.

Дак комната то стала темной из-за С++

ГВ>Некоторые детали мне пришлось опустить. А потом проезд по памяти с разносом всего, включая GC-хип бы бы благом, поскольку заставил бы обратить внимание на эту ошибку намного раньше. К слову сказать, AVE в какой-то момент был у меня единственным методом диагностики. AVE и непосредственно предшествующее ему состояние памяти.


ГВ>>>Ведь сложность поиска бага на самом деле зависит не от "управляемости" кода, а от того, какой это баг.

T>>Совершенно верно. При этом самые сложные для поиска баги — это баги, специфичные для С++, а именно проход по памяти, некорректная её интерпретация и пр.

ГВ>Мантра. Даже обсуждать не хочу. Как раз из-за того, что не раз такие ошибки и делал, и лечил (не только у себя).


Ну вот, в данный момент разбираю дамп. Бага воспроизвелась только один раз. Что посоветуешь?

*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************

FAULTING_IP: 
ntdll!RtlpFindAndCommitPages+116
7c91aa21 66833f00        cmp     word ptr [edi],0

EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 7c91aa21 (ntdll!RtlpFindAndCommitPages+0x00000116)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 0b39b920
Attempt to read from address 0b39b920

...

DEFAULT_BUCKET_ID:  HEAP_CORRUPTION

PRIMARY_PROBLEM_CLASS:  HEAP_CORRUPTION

BUGCHECK_STR:  APPLICATION_FAULT_HEAP_CORRUPTION_INVALID_POINTER_READ_WRONG_SYMBOLS
...
STACK_TEXT:  
0b9ff4e4 7c91a3dc 04fb0000 0b35b000 0b9ff510 ntdll!RtlpFindAndCommitPages+0x116
0b9ff51c 7c911937 01fb0000 00000660 0000006b ntdll!RtlpExtendHeap+0xa6
0b9ff74c 78583db8 04fb0000 00000000 00000655 ntdll!RtlAllocateHeap+0x623
0b9ff76c 0533ceed 00000655 0b9ff798 0533c42f msvcr90!malloc+0x79 [f:\dd\vctools\crt_bld\self_x86\crt\src\malloc.c @ 163]
...


ГВ>>>В managed-коде причины багов ничуть не легче раскапывать, чем в unmanaged, а подчас и тяжелее из-за его всепроникающей "корректности", которая позволяет ему проглатывать то, что валит unmanaged.

T>>Легче из-а отсутствия наиболее противных багов и наличия нормальных исключений с callstack'ами и сообщениями.

ГВ>Вот странное дело. Сколько пишу на этом кошмарном C++, а самые противные баги — из-за бестолковой спецификации. ЧЯДНТ?

У тебя сколько человек в команде и сколько команд работает над одним продуктом?

ГВ>>>У меня даже закралась крамольная мысль, [...]

T>>Контракты тебя спасут. В отличии от С++, в котором даже контракты не помогут, так как ничего не стоит эти контракты кому угодно разрушить без твоего ведома.

ГВ>Ну, в упомянутом случае они спасти не могли, хотя бы в виду исторических причин. А то, знаешь, хорошо решать проблемы с помощью будущих инструментов.


Какой будущий инструмент? Этому инструменту уже много десятков лет. Называется "assert".

T>>Локализованы — это значит, что у тебя не сломается не связанная с этими объектами функциональность. [...] В частности, благодаря наличию метаданных твоя ошибка ищется очень просто: в windbg ты можешь сдампить все объекты интересующиего тебя типа, посмотреть их количество, и проверить все ссылки, кто на что ссылается. В частности, как только тестировщик видит, что приложение падает (из-за нарушения контракта), либо работает некорректно, то он делает дамп, отдает его тебе, ты видишь, что объектов два вместо одного, кричишь WTF, смотришь на код, который их создает и видишь, что этот код ломается в случае параллельного доступа. Все просто и скучно, никакого веселья и гадания на кофейной гуще, как в С++.


ГВ>Хм. Я, вроде, понятно высказался: один объект вместо двух. Если они используются как read-only, ошибок попросту не будет. Вернее, они будут проявляться очень косвенно. Какая именно функциональность поломается — трудно предсказать в любом случае.


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

ГВ>Да и дамп объектов бы не помог... Если я непонятно написал, то уточню: ключом к решению стало добавление защиты от параллельного доступа. Всё остальное было поисками чёрной кошки из-за приключившегося у меня приступа паранойи.


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

T>>>>2) Наличие коллстеков у всех исключений.

ГВ>>>Не надо преувеличивать: сам по себе коллстек показывает лишь на место возникновения сбоя, но ничего не говорит о той цепи причин, которые привели к его возникновению (кроме непосредственной). Об этом было говорено-переговорено лет семь-восемь назад.
T>>В 90% случаев этого достаточно. В С++ нет даже этого. Ты просто знаешь, что что-то где-то сломалось. Что и где — неизвестно. Если не удалось поймать дамп в момент падения, то начинается веселье.

ГВ>Чушь. В C++, в случае выбрасывания исключения я знаю о происходящем ровно столько же, сколько и в C#: что в точке файл... строка... вылетело исключение. Информация о стеке... Ну как, может быть полезна с некоторой вероятностью, но не более того. А о действительных причинах в этот момент я всё равно могу только догадываться.

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

T>>Ситуация из недавней практики: поскольку проект очень большой, то его части собираются в разное время (чтобы оптимизировать время сборки). Однажды произошла такая ситуация, когда версия хедеров перестала соответствовать бинарям (забыли пересобрать). И продукт при этом работал практически всегда, но иногда в очень редких кейзах начинал течь. Сил угрохали на поиск в коде бага море. А в .NET такое невозможно в принципе.


ГВ>И о чём это говорит? Да ни о чём. Собирать модули надо с соблюдением процедуры, больше ничего.

Это говорит о том, что в С++ проблемы можно получить в любом месте и фраза, что неверная интерпретация памяти бывает только [подставить что-то одно] ложная. Неверная интерпретация памяти может произойти по миллиону причин. И для каждой такой причины можно ответить: "надо делать то-то".
лэт ми спик фром май харт
Re[18]: Конец нересурсов
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 21.11.11 09:49
Оценка:
Здравствуйте, Klatu, Вы писали:

V>>Она встречается на несколько порядков чаще в дотнете, да и в нейтиве тоже, чем проходы по памяти.

K>ну это просто вранье или полная некомпетентность

Слушай, найди какой-нибудь другой аргумент, а?

V>>то программисты C# допускают намного больше ошибок, чем программисты на C++

K>Я пока что не встречал более пафосных говнокодеров, чем на С++. Вот это — точно медицинский факт. Каждое нубло, которое накропало пару примитивных программок на С++ — уже считает себя гуру

Давай уж начистоту: "вы все [плохое слово по выбору], а я в белом!" Так хоть честно будет.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[21]: Конец нересурсов
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 21.11.11 10:02
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, Геннадий Васильев, Вы писали:


ГВ>>>ЧСХ, без моего желания C++ тоже не начнёт вольным образом реинтерпретировать память. А ошибки, связанные с нарушениями инвариантов могут быть абсолютно в любом коде — managed, unmanaged, свой, чужой — без разницы.


G>>Неверно. Ты напишешь функцию, которая к полю объекта обращается. А кто-то до вызова твоей функции выполнит delete объекта, а потом на его месте новый создаст. Причина ошибки в таких случаях может находиться очень далеко от места возникновения, в отличии от managed, который еще и staktrace покажет и можно будет спокойно по дереву вызовов пройтись и узнать кто неверные данные передал.


ГВ>Ясное дело, в managed с этим намного лучше: ссылку на объект, к которому моя функция будет обращаться, уже давно обнулили, но специально ради моей функции держат в памяти уже забытую всеми остальными копию. Благодарствую за любезность!


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


ГВ>>>Дальше всё пошло своим чередом: разобрались, поправили, вытерли пот со лба, облегчённо вздохнули. Однако я вынес из этого несколько очень полезных для себя уроков.


ГВ>>>1) Нельзя вестись на поводу у дурацких стереотипов, что в AVE всегда виноват unmanaged.

G>>Ок, докажи обратное. Когда чисто managed код вызывает AVE.
ГВ>Что — обратное?
Дальше написано. Пример когда чисто managed код вызывает ave.

ГВ>>>2) Managed-код превосходно замаскировал ошибки concurrency и маскировал бы их дальше, если бы именно unmanaged не разорался во всю глотку о том, что что-то пошло не так.

G>>То есть managed код работал, а unmanaged таки падал? Ведь именно unmanaged не был спроектирован под cuncurrency.

ГВ>Умничка. Именно дотнетный код — работал. Ну, по вашему же, если эксцепшенов нет, значит код — работает! Возьми с полки пирожок. Ты, кстати, не у конкурентов, часом работаешь? Надо посоветовать, чтобы тебе зарплату подняли. Скажи, эдипов папа посоветовал.


Не уходит от вопроса. Ты не написал что были какие проблемы непосредственно в managed, ты сказал что он не так вызывал unmanaged, но сам unmanaged этому никак не противился.
То есть переписал unmanaged так чтобы не было этих проблема можно было вообще исключить эту проблему.

ГВ>>>3) Если бы не unmanaged, поиски тщательно замаскированной ошибки стали бы для нас чем-то вроде специальной олимпиады: главное не победа, главное — держаться подальше;

G>>Без unmanaged скорее всего косяк был бы найден раньше ибо в managed из unmanaged не попадет сведений о threading model вызываемого кода.

ГВ>Без unmanaged ошибка не была бы найдена вообще. Но она от этого никуда бы не делась

А в чем тогда ошибка? И почему она не была бы найдена? Или ты что-то не договариваешь ил просто пытаешься свалить вину.
Re[22]: Конец нересурсов
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 21.11.11 10:03
Оценка:
Здравствуйте, mrTwister, Вы писали:

ГВ>>Сам начинает? А он как это делает, по вторникам, или по пятницам?

T>Бывает и по вторникам, бывает и по пятницам. Ты же понимаешь, что когда программу пишешь только ты, это совсем не тоже самое, когда её пишут человек 100, находящихся в разных отделах. А ты пытаешься свой локальный опыт экстраполировать на все случаи, и говоришь, что мол, я вот никогда с этими проблемами не сталкивался, значит их нет.

Если ты заметил, то я на все случаи свой опыт не экстраполирую. Напротив, я говорю о некорректности таких экстраполяций.

ГВ>>Да вот тем самым, когда вместо двух объектов оказывался один.

T>И что? При чем тут управляемость кода?

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

ГВ>>Нет, именно теми словами, которыми написано: трудно искать чёрную кошку в тёмной комнате, когда её нет.

T>Дак комната то стала темной из-за С++

Нет, комната стала тёмной по другим причинам. Пафосно выражаясь, C++ — это были те искры, которые позволили найти выход из этой комнаты.

ГВ>>Мантра. Даже обсуждать не хочу. Как раз из-за того, что не раз такие ошибки и делал, и лечил (не только у себя).

T>Ну вот, в данный момент разбираю дамп. Бага воспроизвелась только один раз. Что посоветуешь?

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

ГВ>>Вот странное дело. Сколько пишу на этом кошмарном C++, а самые противные баги — из-за бестолковой спецификации. ЧЯДНТ?

T>У тебя сколько человек в команде и сколько команд работает над одним продуктом?

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

ГВ>>>>У меня даже закралась крамольная мысль, [...]

T>>>Контракты тебя спасут. В отличии от С++, в котором даже контракты не помогут, так как ничего не стоит эти контракты кому угодно разрушить без твоего ведома.
ГВ>>Ну, в упомянутом случае они спасти не могли, хотя бы в виду исторических причин. А то, знаешь, хорошо решать проблемы с помощью будущих инструментов.
T>Какой будущий инструмент? Этому инструменту уже много десятков лет. Называется "assert".

А... Я подумал про design contracts из FW 4. Ну так assert-ом по сути и спаслись.

ГВ>>Хм. Я, вроде, понятно высказался: один объект вместо двух. Если они используются как read-only, ошибок попросту не будет. Вернее, они будут проявляться очень косвенно. Какая именно функциональность поломается — трудно предсказать в любом случае.

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

Во-во, знакомо. Ошибка — это только если exception, всё остальное — "так и надо".

ГВ>>Да и дамп объектов бы не помог... Если я непонятно написал, то уточню: ключом к решению стало добавление защиты от параллельного доступа. Всё остальное было поисками чёрной кошки из-за приключившегося у меня приступа паранойи.

T>В дампе ты бы увидел, что было создано два объекта вместо одного. Дальше все тривиально.

Ничего бы я там не увидел... Да и собственно, я говорил о совершенно других вещах.

ГВ>>Чушь. В C++, в случае выбрасывания исключения я знаю о происходящем ровно столько же, сколько и в C#: что в точке файл... строка... вылетело исключение. Информация о стеке... Ну как, может быть полезна с некоторой вероятностью, но не более того. А о действительных причинах в этот момент я всё равно могу только догадываться.

T>Строчку файла ты узнаешь только если исключение соизволит тебе это сообщить. Код бывает не только твой, но и чужой, на который ты повлиять не можешь.

Тоже справедливо. А исходников этого самого чужого кода у меня нет?

T>>>Ситуация из недавней практики: поскольку проект очень большой, то его части собираются в разное время (чтобы оптимизировать время сборки). Однажды произошла такая ситуация, когда версия хедеров перестала соответствовать бинарям (забыли пересобрать). И продукт при этом работал практически всегда, но иногда в очень редких кейзах начинал течь. Сил угрохали на поиск в коде бага море. А в .NET такое невозможно в принципе.

ГВ>>И о чём это говорит? Да ни о чём. Собирать модули надо с соблюдением процедуры, больше ничего.
T>Это говорит о том, что в С++ проблемы можно получить в любом месте и фраза, что неверная интерпретация памяти бывает только [подставить что-то одно] ложная. Неверная интерпретация памяти может произойти по миллиону причин. И для каждой такой причины можно ответить: "надо делать то-то".

Так и надо делать "то-то".
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[21]: Конец нересурсов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.11.11 10:28
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>Нет, именно теми словами, которыми написано: трудно искать чёрную кошку в тёмной комнате, когда её нет.


Так вот в том то и дело, что AVE это черная кошка. Означает, что что то не так и ничего больше.
Я буквально неделю назад выловил ошибку в managed коде, тоже с внезапным concurrency связанную. Только там было нарушение инвариантов, а не AVE. Просмотр небольшого кусочка кода, в котором исключение произошло, сразу выявил, что это нарушение могло произойти только из-за гонок. Остальное было тривиально. А было бы AVE, точно так же несколько дней искал бы черную кошку в темной комнате.

ГВ>это, в сущности, не так уж плохо, поскольку заставляет внимательнее относиться к программированию.


Да, этот аргумент меня всегда убивал наповал. Я даже не знаю, что на это ответить.
... << RSDN@Home 1.2.0 alpha 5 rev. 1537 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[13]: Конец нересурсов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.11.11 10:28
Оценка: 1 (1)
Здравствуйте, vdimas, Вы писали:

V>Ты сим постом сделал такое предположение о кач-ве дотнетных специалистов, что обсуждать сразу стало нечего.


А ты этим постом тоже кое что наглядно продемонстрировал.
Нет никакого такого качества дотнетных специалистов. Есть просто качество специалистов. И от того, что конкретного человека ты с шарпа на плюсы пересадишь, он умнее не станет.
... << RSDN@Home 1.2.0 alpha 5 rev. 1537 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[27]: Конец нересурсов
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 21.11.11 10:40
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>Ну как тебе сказать. Я знаю довольно много плюсовиков (во всяком случае, совсем не единицы), которые просто не станут реализовывать свои механизмы управления памятью, поскольку имеющихся общедоступных средств вполне достаточно. Хотя это вполне в их силах. Кстати, никаких "качественных" или "некачественных" политик управления памятью не бывает. Они соответствуют либо одним требованиям, либо другим. И собственно говоря, управление памятью почти всегда согласуется с архитектурой приложения, впрочем, это отдельный разговор.


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

Не ясно, что ты хотел сказать "управление памятью почти всегда согласуется с архитектурой приложения" — это как понять ? Кто выполняет это согласование ? какая квалификация должна быть у того кто выполняет это согласование ? Какие архитектуры уже согласованы с той политикой управления что искаропки ?
Re[22]: Конец нересурсов
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 21.11.11 10:42
Оценка:
Здравствуйте, AndrewVK, Вы писали:

ГВ>>Нет, именно теми словами, которыми написано: трудно искать чёрную кошку в тёмной комнате, когда её нет.

AVK>Так вот в том то и дело, что AVE это черная кошка. Означает, что что то не так и ничего больше.

"Отсутствующей кошкой" я назвал ошибку в unmanaged. AVE как раз — очень даже ощутимый кошак.

AVK>Я буквально неделю назад выловил ошибку в managed коде, тоже с внезапным concurrency связанную. Только там было нарушение инвариантов, а не AVE. Просмотр небольшого кусочка кода, в котором исключение произошло, сразу выявил, что это нарушение могло произойти только из-за гонок. Остальное было тривиально. А было бы AVE, точно так же несколько дней искал бы черную кошку в темной комнате.


Здесь главное — что искомой "кошки" (ошибки в unmanaged) не было. Было банальное нарушение инварианта порядка доступа и в виду отсутствия защиты от такого нарушения...

P.S.: Прерываюсь до вечера.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.